如何将 Django 的模型字段"对象"的类型提示到动态生成的类?



我的Django项目中有一个Team模型。我用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()

当我尝试执行Team.objects.active()时,mypy会给出以下错误:

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

如果我明确定义了一个TeamManager类,就不会有问题。如何将Django模型字段objects的类型提示给动态生成的类?

基于Manager[Any],我假设您已经在使用django-stubs

不幸的是,似乎有一个悬而未决的问题,使QuerySet.as_manager在其所附的模型上通用,但尚未解决。

即使解决该问题的PR被合并,恐怕也无法解决您的直接问题,因为as_manager需要是通用的,而不是用于创建管理器的通用QuerySet子类,以便.active可用,并且与Team相关的属性可用。

在这方面,不幸的是,另一个公关相当陈旧,似乎恰当地解决了你的问题。

为了MyPy,我使用了一个小的switch-a-roo来解决这个问题:

_Q = TypeVar("_Q", bound="WorkflowQuerySet")

class WorkflowQuerySet(models.QuerySet["WorkflowModel"]):
"""
Queryset for workflow objects.
"""
def count_objects(self) -> int:
raise NotImplementedError
def latest_objects(self: _Q) -> _Q:
raise NotImplementedError

if TYPE_CHECKING:
# Create a type MyPy understands
class WorkflowManager(models.Manager["WorkflowModel"]):
def count_objects(self) -> int:
...
def latest_objects(self) -> _Q:
...

else:
WorkflowManager = WorkflowQuerySet.as_manager

class WorkflowModel(models.Model):
"""
A model that has workflow.
"""
objects = WorkflowManager()

以下是我使用泛型和typevar 的答案

from typing import Generic, TypeVar
from django.db import models
class BookQueryset(models.QuerySet['Book']):
...
class Book(models.Model):
objects: BookQueryset = BookQueryset.as_manager()

book = Book.objects.all()[0]

如果你检查书籍是类型书籍

最新更新