Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to hint the type of Django's model field `objects` to a dynamically generated class?

I have a Team model in my Django project. I create its custom model manager with QuerySet.as_manager().

class TeamQuerySet(models.QuerySet):
    def active(self) -> "models.QuerySet[Team]":
        return self.filter(is_active=True)

class Team(models.Model):
    is_active = models.BooleanField()

    objects = TeamQuerySet.as_manager()

When I try to execute Team.objects.active(), mypy gives the following error:

error: "Manager[Any]" has no attribute "active"
In [5]: Team.objects
Out[5]: <django.db.models.manager.ManagerFromTeamQuerySet at 0x10eee1f70>

If I was explicitly defining a TeamManager class, there would be not a problem. How can I hint the type of Django model field objects to a dynamically generated class?

like image 868
viam0Zah Avatar asked Aug 04 '20 08:08

viam0Zah


People also ask

What is __ str __ In Django model?

The __str__() method is called whenever you call str() on an object. Django uses str(obj) in a number of places. Most notably, to display an object in the Django admin site and as the value inserted into a template when it displays an object.

What does field type signifies in Django models?

Fields in Django are the data types to store a particular type of data. For example, to store an integer, IntegerField would be used. These fields have in-built validation for a particular data type, that is you can not store “abc” in an IntegerField. Similarly, for other fields.

Is there a list field for Django models?

Mine is simpler to implement, and you can pass a list, dict, or anything that can be converted into json. In Django 1.10 and above, there's a new ArrayField field you can use.

What is the type of QuerySet in Django?

A QuerySet is a collection of data from a database. A QuerySet is built up as a list of objects. QuerySets makes it easier to get the data you actually need, by allowing you to filter and order the data.


1 Answers

Based on the Manager[Any] I assume you are already using django-stubs.

Unfortunately it looks like there's an open issue to make QuerySet.as_manager generic over the model it's attached to that has not been resolved yet.

Even if the PR addressing the issue got merged I'm afraid it wouldn't address your immediate issue because the as_manager needs to be generic over the generic QuerySet subclass used to create the manager in order for both .active to be available and attributes relating to Team be available.

In this regard this other PR, which is unfortunately quite stale, seems to properly address your issue.

like image 145
Simon Charette Avatar answered Oct 18 '22 14:10

Simon Charette