Add support for inline from_queryset in model classes (#1045)

* Add support for inline from_queryset in model classes

This adds support for calling <Manager>.from_queryset(<QuerySet>)()
inline in models, for example like this:

    class MyModel(models.Model):
        objects = MyManager.from_queryset(MyQuerySet)()

This is done by inspecting the class body in the transform_class_hook

* Fix missing methods on copied manager

* Add test and other minor tweaks

* Always create manager at module level

When the manager is added at the class level, which happened when it was
created inline in the model body, it's not possible to retrieve the
manager again based on fullname. That lead to problems with inheritance
and the default manager.
This commit is contained in:
Sigurd Ljødal
2022-07-13 09:04:44 +02:00
committed by GitHub
parent 2e84c03632
commit 830d74b493
7 changed files with 251 additions and 186 deletions

View File

@@ -24,7 +24,6 @@ from mypy_django_plugin.lib import fullnames, helpers
from mypy_django_plugin.transformers import fields, forms, init_create, meta, querysets, request, settings
from mypy_django_plugin.transformers.managers import (
create_new_manager_class_from_from_queryset_method,
fail_if_manager_type_created_in_model_body,
resolve_manager_method,
)
from mypy_django_plugin.transformers.models import (
@@ -237,11 +236,6 @@ class NewSemanalDjangoPlugin(Plugin):
django_context=self.django_context,
)
elif method_name == "from_queryset":
info = self._get_typeinfo_or_none(class_fullname)
if info and info.has_base(fullnames.BASE_MANAGER_CLASS_FULLNAME):
return fail_if_manager_type_created_in_model_body
return None
def get_base_class_hook(self, fullname: str) -> Optional[Callable[[ClassDefContext], None]]: