首页 > 解决方案 > Python / Django - Mypy:表达式的类型为“Type[ModelInstance]”,变量的类型为“ModelInstance”

问题描述

我正在开发一个为前端提供 GraphQL api 的 Django 应用程序。我正在使用 mypy 进行类型检查,并且在运行 mypy 时遇到了我不理解的错误

运行时出现以下错误:

api/schema.py:50: error: Incompatible types in assignment (expression has type "Type[Academy]", variable has type "Academy")
api/schema.py:57: error: Incompatible types in assignment (expression has type "Type[School]", variable has type "School")
api/schema.py:64: error: Incompatible types in assignment (expression has type "Type[AcademyGroup]", variable has type "AcademyGroup")

这是 mypy 正在检查的代码

class AcademyType(DjangoObjectType):
    class Meta:
        model: Academy = Academy
        filter_fields: List[str] = ['name', 'domain', 'slug']
        interfaces: Tuple = (relay.Node,)


class SchoolType(DjangoObjectType):
    class Meta:
        model: School = School
        filter_fields: List[str] = ['name', 'academy']
        interfaces: Tuple = (relay.Node,)


class AcademyGroupType(DjangoObjectType):
    class Meta:
        model: AcademyGroup = AcademyGroup
        filter_fields: List[str] = ['name', 'academy']
        interfaces: Tuple = (relay.Node,)

所以一直失败的行是变体model: AcademyGroup = AcademyGroup,但这只是我的代码中发生的“Django模型作为类型”定义(并且似乎没有产生错误)

因此,我不确定我在这里做错了什么,所以任何帮助将不胜感激。

标签: pythondjangomypy

解决方案


你的model属性类型不是类本身,而是一个Type. 确实,如果您说model = Academy,那么 的类型确实model不是对象type(model) == type(Academy) == Type它是类的引用,此类的类型是 的(子类)。您还可以使用[python-doc]来指定类型的(基)类,这意味着它是 的类型或 的子类:AcademyAcademy TypeType[…]Type[C]CC

因此,您应该将其注释为:

from typing import Type

class AcademyType(DjangoObjectType):
    class Meta:
        model: Type[Academy] = Academy
        filter_fields: List[str] = ['name', 'domain', 'slug']
        interfaces: Tuple = (relay.Node,)


class SchoolType(DjangoObjectType):
    class Meta:
        model: Type[School] = School
        filter_fields: List[str] = ['name', 'academy']
        interfaces: Tuple = (relay.Node,)


class AcademyGroupType(DjangoObjectType):
    class Meta:
        model: Type[AcademyGroup] = AcademyGroup
        filter_fields: List[str] = ['name', 'academy']
        interfaces: Tuple = (relay.Node,)

推荐阅读