Skip to content

Commit

Permalink
Allow lookups on .annotate fields
Browse files Browse the repository at this point in the history
  • Loading branch information
sterliakov committed Sep 20, 2024
1 parent f2f7bb5 commit dc3a33b
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 7 deletions.
12 changes: 6 additions & 6 deletions mypy_django_plugin/django/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -482,12 +482,12 @@ def resolve_lookup_expected_type(
try:
solved_lookup = self.solve_lookup_type(model_cls, lookup)
except FieldError as exc:
if (
helpers.is_annotated_model(model_instance.type)
and model_instance.extra_attrs
and lookup in model_instance.extra_attrs.attrs
):
return model_instance.extra_attrs.attrs[lookup]
if helpers.is_annotated_model(model_instance.type) and model_instance.extra_attrs:
# If the field comes from .annotate(), we assume Any for it
# and allow chaining any lookups.
lookup_base_field, *_ = lookup.split("__")
if lookup_base_field in model_instance.extra_attrs.attrs:
return model_instance.extra_attrs.attrs[lookup_base_field]

msg = exc.args[0]
if model_instance.extra_attrs:
Expand Down
21 changes: 20 additions & 1 deletion tests/typecheck/managers/querysets/test_annotate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@
username = models.CharField(max_length=100)
- case: annotate_currently_allows_lookups_of_non_existent_field
- case: annotate_rejects_lookups_of_non_existent_field
main: |
from myapp.models import User
from django.db.models.expressions import F
Expand Down Expand Up @@ -395,3 +395,22 @@
class Entry(models.Model):
blog = models.ForeignKey(Blog, on_delete=models.CASCADE)
- case: test_annotate_allows_any_lookups_in_filter
main: |
from django.db import models
from myapp.models import Blog
qs = Blog.objects.annotate(distance=0)
qs.filter(distance=10)
qs.filter(distance__lt=10)
qs.filter(distance__lt__lt=10)
qs.filter(distance__unknown_lookup=10)
installed_apps:
- myapp
files:
- path: myapp/__init__.py
- path: myapp/models.py
content: |
from django.db import models
class Blog(models.Model): pass

0 comments on commit dc3a33b

Please sign in to comment.