Django 模型的类型注释
Type annotations for Django models
我正在做一个 Django 项目。由于这是一个新项目,我想用 python 3.6+ 类型注释对其进行完整注释。我正在尝试注释模型,但我很难找到一个好的方法。
我们以IntegerField
为例。我看到两个注释选项:
# number 1
int_field: int = models.IntegerField()
# number 2
int_field: models.IntegerField = models.IntegerField()
1 号在 mypy 中失败:
Incompatible types in assignment (expression has type "IntegerField[<nothing>, <nothing>]", variable has type "int")
2 号对于 mypy 是可以的,但是 IDE 作为 PyCharm 无法解决它并且经常抱怨使用了错误的类型。
是否有任何最佳实践来正确注释模型,以满足 mypy 和 IDE 的要求?
Django 模型(和其他组件)很难注释,因为它们背后有很多魔法,好消息是一群 酷开发者 已经完成了这项艰巨的工作为我们工作。
django-stubs 提供一组存根和 mypy 插件,为 Django 提供静态类型和类型推断。
例如,具有以下模型:
from django.contrib.auth import get_user_model
from django.db import models
User = get_user_model()
class Post(models.Model):
title = models.CharField(max_length=255)
pubdate = models.DateTimeField()
author = models.ForeignKey(User, 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_settings_module
)
完成后,mypy 将能够推断和检查 Django 模型(和其他组件)的注释。
demo$ mypy .
Success: no issues found in 5 source files
下面是小视图中的用法示例:
from django.db.models.query import QuerySet
from django.http import HttpRequest, HttpResponse
from django.shortcuts import render
from demo.models import Post
def _get_posts() -> 'QuerySet[Post]':
return Post.objects.all()
def posts(request: HttpRequest, template: str='posts.html') -> HttpResponse:
return render(request, template, {'posts': _get_posts()})
再一次,mypy 对提供的注释感到满意:
demo$ mypy .
Success: no issues found in 7 source files
同样,Django Rest Framework 的包也可用:djangorestframework-stubs.
我正在做一个 Django 项目。由于这是一个新项目,我想用 python 3.6+ 类型注释对其进行完整注释。我正在尝试注释模型,但我很难找到一个好的方法。
我们以IntegerField
为例。我看到两个注释选项:
# number 1
int_field: int = models.IntegerField()
# number 2
int_field: models.IntegerField = models.IntegerField()
1 号在 mypy 中失败:
Incompatible types in assignment (expression has type "IntegerField[<nothing>, <nothing>]", variable has type "int")
2 号对于 mypy 是可以的,但是 IDE 作为 PyCharm 无法解决它并且经常抱怨使用了错误的类型。
是否有任何最佳实践来正确注释模型,以满足 mypy 和 IDE 的要求?
Django 模型(和其他组件)很难注释,因为它们背后有很多魔法,好消息是一群 酷开发者 已经完成了这项艰巨的工作为我们工作。
django-stubs 提供一组存根和 mypy 插件,为 Django 提供静态类型和类型推断。
例如,具有以下模型:
from django.contrib.auth import get_user_model
from django.db import models
User = get_user_model()
class Post(models.Model):
title = models.CharField(max_length=255)
pubdate = models.DateTimeField()
author = models.ForeignKey(User, 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_settings_module
)
完成后,mypy 将能够推断和检查 Django 模型(和其他组件)的注释。
demo$ mypy .
Success: no issues found in 5 source files
下面是小视图中的用法示例:
from django.db.models.query import QuerySet
from django.http import HttpRequest, HttpResponse
from django.shortcuts import render
from demo.models import Post
def _get_posts() -> 'QuerySet[Post]':
return Post.objects.all()
def posts(request: HttpRequest, template: str='posts.html') -> HttpResponse:
return render(request, template, {'posts': _get_posts()})
再一次,mypy 对提供的注释感到满意:
demo$ mypy .
Success: no issues found in 7 source files
同样,Django Rest Framework 的包也可用:djangorestframework-stubs.