sbdchd / django-types

:doughnut: Type stubs for Django
MIT License
188 stars 62 forks source link

Error when trying to access `Group.user_set` #95

Closed simensol closed 2 years ago

simensol commented 2 years ago

If I try this:

from django.contrib.auth.models import Group

my_group = Group.objects.get_by_natural_key(name="group_A")

my_group.user_set

Pyright complains that:

Cannot access member "user_set" for type "Group"
  Member "user_set" is unknown Pylance(reportGeneralTypeIssues)

I tried to add

class Group(Group):
    if TYPE_CHECKING:
        user_set = RelatedManager["User"]()

but Pylance still complains. How can I add user_set to Group?

last-partizan commented 2 years ago

That's a good question!

Currently i'm using following hack: i have myproejct.auth.compat with imported model User, to which i added all needed related managers.

And instead of importing everything from django.contrib i use my auth.compat.

I hope there is better approach.

@sbdchd @bellini666 any ideas?

bellini666 commented 2 years ago

Your approach is correct, but like @last-partizan , I think you need to import your own Group, even if for typing (e.g. if TYPE_CHECKING import yours, else import the real one).

Also, you don't need to if TYPE_CHECKING there, just do user_set: "RelatedManager[User]". For example, this is from an open source lib I'm developing: https://github.com/blb-ventures/strawberry-django-plus/blob/master/tests/models.py#L49 . This is a simple example that I use there for testing, but I do the same for all the projects I work on and I have no issues!

simensol commented 2 years ago

Then I follow the recommended approach. This is what I ended up with:

if TYPE_CHECKING:
    from django.contrib.auth.models import Group as AuthGroup
    from django.contrib.auth.models import GroupManager
    from django.db.models.manager import RelatedManager

    class Group(AuthGroup):
        """
        Makes `objects` and `user_set` available to type checkers. See
        <https://github.com/sbdchd/django-types#foreignkey-ids-and-related-names-as-properties-in-orm-models>.
        """
        objects = GroupManager()
        user_set = RelatedManager["User"]()

else:
    from django.contrib.auth.models import Group