django-stubs icon indicating copy to clipboard operation
django-stubs copied to clipboard

Error when overriding user manager

Open lfrodrigues opened this issue 5 years ago • 2 comments

Bug report

I'm overwritting the user manager like:

class MyUserManager(BaseUserManager):
    def create_user(
        self,
        facebook_email: str,
        facebook_first_name: str,
        facebook_last_name: str,
        facebook_uid: str,
        facebook_access_token: str,
        **extra_fields
    ):
    .....


class User(AbstractBaseUser):
    (...)
    objects = MyUserManager()

What's wrong

mypy returns:

accounts/models.py:31: error: Missing type parameters for generic type "BaseUserManager"

How is that should be

It should just work :)

System information

  • OS: Ubuntu 18.04
  • python version: 3.6
  • django version: 2.2
  • mypy version: 0.761
  • django-stubs version: 1.4.0

lfrodrigues avatar Feb 01 '20 08:02 lfrodrigues

Couldn't/shouldn't this be resolved by doing the following?

class MyUserManager(BaseUserManager["User"]):
    ...
    
class User(AbstractBaseUser):
    ...
    objects = MyUserManager()

If the PR linked to close this issue, #360 removing arguments, is merged, I don't think there's a possibility to properly type Manager.model for the user manager?

https://github.com/typeddjango/django-stubs/blob/8d8b8cd1fc8b54eac799905dbbffc4e21708b6da/django-stubs/db/models/manager.pyi#L34

Which in addition, if I'm overriding e.g. def create_user and use something like:

user = self.model(*args, **kwargs)
user.save()
return user  # <- `user` is now `Any` as `self.model` can't be resolved..

I'm returning Any..

flaeppe avatar Jun 17 '22 11:06 flaeppe

I was suffering the same issue, creating a custom manager which needed to be typed with the model class that hadn't been declared yet because the model required the manager and doing it like this worked so i think this isn't an issue:

class PublishedManager(models.Manager["Post"]):
        def get_queryset(self) -> models.QuerySet["Post"]:
            return super().get_queryset() .filter(status=1)

adambirds avatar Jun 19 '22 01:06 adambirds