Skip to content

Commit

Permalink
Check calls to filtering manager methods involving ManyToManyField (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
flaeppe authored Jul 25, 2024
1 parent d747285 commit d6010fd
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 1 deletion.
2 changes: 1 addition & 1 deletion mypy_django_plugin/django/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ def __init__(self, django_settings_module: str) -> None:
def model_modules(self) -> Dict[str, Dict[str, Type[Model]]]:
"""All modules that contain Django models."""
modules: Dict[str, Dict[str, Type[Model]]] = defaultdict(dict)
for concrete_model_cls in self.apps_registry.get_models():
for concrete_model_cls in self.apps_registry.get_models(include_auto_created=True, include_swapped=True):
modules[concrete_model_cls.__module__][concrete_model_cls.__name__] = concrete_model_cls
# collect abstract=True models
for model_cls in concrete_model_cls.mro()[1:]:
Expand Down
1 change: 1 addition & 0 deletions mypy_django_plugin/transformers/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -932,6 +932,7 @@ def create_many_related_manager(self, model: Instance) -> None:
helpers.set_many_to_many_manager_info(
to=model.type, derived_from="_default_manager", manager_info=related_manager_info
)
helpers.add_new_manager_base(self.api, related_manager_info.fullname)


class MetaclassAdjustments(ModelClassInitializer):
Expand Down
26 changes: 26 additions & 0 deletions tests/typecheck/fields/test_related.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1472,3 +1472,29 @@
class Second(Parent):
...
- case: test_m2m_models_manager_filter_kwargs_checked
main: |
from myapp.models import MyModel, Other
MyModel.objects.filter(xyz__isnull=False) # E: Cannot resolve keyword 'xyz' into field. Choices are: id, others [misc]
MyModel.objects.get(xyz__isnull=False) # E: Cannot resolve keyword 'xyz' into field. Choices are: id, others [misc]
MyModel.objects.exclude(xyz__isnull=False) # E: Cannot resolve keyword 'xyz' into field. Choices are: id, others [misc]
other = Other()
other.mymodel_set.filter(xyz__isnull=True) # E: Cannot resolve keyword 'xyz' into field. Choices are: id, mymodel, mymodel_id, other, other_id [misc]
other.mymodel_set.get(xyz__isnull=True) # E: Cannot resolve keyword 'xyz' into field. Choices are: id, mymodel, mymodel_id, other, other_id [misc]
other.mymodel_set.exclude(xyz__isnull=True) # E: Cannot resolve keyword 'xyz' into field. Choices are: id, mymodel, mymodel_id, other, other_id [misc]
MyModel.others.through.objects.filter(xyz__isnull=False) # E: Cannot resolve keyword 'xyz' into field. Choices are: id, mymodel, mymodel_id, other, other_id [misc]
MyModel.others.through.objects.get(xyz__isnull=False) # E: Cannot resolve keyword 'xyz' into field. Choices are: id, mymodel, mymodel_id, other, other_id [misc]
MyModel.others.through.objects.exclude(xyz__isnull=False) # E: Cannot resolve keyword 'xyz' into field. Choices are: id, mymodel, mymodel_id, other, other_id [misc]
installed_apps:
- myapp
files:
- path: myapp/__init__.py
- path: myapp/models.py
content: |
from django.db import models
class Other(models.Model):
...
class MyModel(models.Model):
others = models.ManyToManyField(Other)

0 comments on commit d6010fd

Please sign in to comment.