Python Django模型的类型注释
我在做一个Django项目。由于这是一个新项目,我希望使用python 3.6+类型注释对其进行完整注释。我试图注释模型,但我很难找到一个好的方法 让我们以Python Django模型的类型注释,python,django,type-annotation,Python,Django,Type Annotation,我在做一个Django项目。由于这是一个新项目,我希望使用python 3.6+类型注释对其进行完整注释。我试图注释模型,但我很难找到一个好的方法 让我们以IntegerField为例。我看到了两种注释它的选择: #编号1 int_字段:int=models.IntegerField() #二号 int_字段:models.IntegerField=models.IntegerField() mypy中的数字1失败: Incompatible types in assignment (expr
IntegerField
为例。我看到了两种注释它的选择:
#编号1
int_字段:int=models.IntegerField()
#二号
int_字段:models.IntegerField=models.IntegerField()
mypy中的数字1失败:
Incompatible types in assignment (expression has type "IntegerField[<nothing>, <nothing>]", variable has type "int")
赋值中不兼容的类型(表达式的类型为“IntegerField[,]”,变量的类型为“int”)
对于mypy来说,第2个是可以的,但是作为PyCharm的IDE无法解决这个问题,并且经常抱怨使用了错误的类型
有什么最佳实践可以正确地注释模型,从而满足mypy和IDE的要求吗?Django模型(和其他组件)很难注释,因为它们背后有很多魔力,好消息是一群很酷的开发人员已经为我们做了艰苦的工作
提供一组存根和mypy插件,为Django提供静态类型和类型推断
例如,具有以下模型:
从django.contrib.auth导入get\u user\u模型
从django.db导入模型
User=get\u User\u model()
班级职务(models.Model):
title=models.CharField(最大长度=255)
pubdate=models.DateTimeField()
author=models.ForeignKey(用户,on_delete=models.CASCADE)
mypy会抱怨说:
demo$ mypy .
demo/models.py:9: error: Need type annotation for 'title'
demo/models.py:10: error: Need type annotation for 'pubdate'
demo/models.py:11: error: Need type annotation for 'author'
Found 3 errors in 1 file (checked 5 source files)
要修复它,只需安装软件包就足够了
pip install django-stubs
并使用以下内容创建setup.cfg
文件:
[mypy]
plugins =
mypy_django_plugin.main
strict_optional = True
[mypy.plugins.django-stubs]
django_settings_module = demo.settings
(不要忘记根据您的设置模块更新django\u设置\u模块
)
完成后,mypy将能够推断并检查Django模型(和其他组件)的注释
以下是小视图中的用法示例:
来自django.db.models.query导入QuerySet
从django.http导入HttpRequest,HttpResponse
从django.shortcuts导入渲染
从demo.models导入帖子
def_get_posts()->“QuerySet[Post]”:
return Post.objects.all()
def posts(请求:HttpRequest,模板:str='posts.html')->HttpResponse:
返回呈现(请求,模板,{'posts':_get_posts()})
mypy再次对提供的注释感到满意:
demo$ mypy .
Success: no issues found in 7 source files
同样,Django Rest Framework的一个包也可用:。因为您似乎在令人满意的工具上投入了大量时间,您可能会惊讶地听说您所做的,不是类型批注不适合的:静态类型。您不是在寻找类似的东西吗?看起来mypy django不为模型提供类型批注:@KlausD。-我不确定我是否明白你的意思,你能详细说明一下吗?@aaron:不,因为那肯定是错的。问题在于,Django模型是一种完全不同的野兽;类包含字段,实例包含具体值。类型随上下文而变化,实例没有
整型字段
,但是如果使用联合
,那么所有访问该字段的代码都必须考虑这种可能性。我实际上发现了这一点,但我用错了。感谢您的详细回答,帮助我向前迈进。看起来该插件也试图执行Django项目本身,因此如果它依赖于特定环境或类似环境,它将无法运行。
demo$ mypy .
Success: no issues found in 7 source files