Django:向后输入/相关名称/外键关系

fli*_*lix 4 python django type-hinting django-stubs

假设我们有以下模型:

class Site(models.Model):
    # This is djangos build-in Site Model
    pass

class Organization(models.Model):
    site = models.OneToOneField(Site)
Run Code Online (Sandbox Code Playgroud)

如果我在其他班级的某个地方使用它:

organization = self.site.organization
Run Code Online (Sandbox Code Playgroud)

然后 mypy 抱怨道:

Site has no attribute "organization"
Run Code Online (Sandbox Code Playgroud)

我怎样才能让mypy在这里开心?

Jes*_*sse 8

Django 在运行时添加向后关系,这些关系不会被mypy仅进行静态分析的捕获。

为了使其mypy快乐(并使其与编辑器的自动完成功能一起使用),您需要添加显式类型提示Site

class Site(models.Model):
    organization: "Organization"

class Organization(models.Model):
    site = models.OneToOneField(Site)
Run Code Online (Sandbox Code Playgroud)

需要在类型周围使用引号,因为我们正在定义类型之前进行前向引用。Organization

对于外键和多对多关系,您可以执行相同的操作,但使用QuerySet类型提示:

class Organization(models.Model):
    site = models.OneToOneField(Site)
    employees: models.QuerySet["Employee"]

class Employee(models.Model):
    organization = models.ForeignKey(
        Organization,
        on_delete=models.CASCADE,
        related_name="employees",
    )
Run Code Online (Sandbox Code Playgroud)

编辑:有一个django-stubs包旨在与 集成mypy,但我个人没有使用过它。它可以为此提供解决方案,而无需向模型显式添加类型提示。