Os modelos do Django (e outros componentes) são difíceis de anotar porque há muita mágica por trás deles, uma boa notícia é que um grupo de desenvolvedores legais já fez o trabalho duro por nós.
O django-stubs fornece um conjunto de stubs e plugins mypy que fornecem tipos estáticos e inferência de tipos para o Django.
Por exemplo, com o seguinte modelo:
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 reclamaria dizendo:
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)
Para corrigi-lo, basta instalar o pacote
pip install django-stubs
e crie um setup.cfg
arquivo com o seguinte:
[mypy]
plugins =
mypy_django_plugin.main
strict_optional = True
[mypy.plugins.django-stubs]
django_settings_module = demo.settings
(Não esqueça de atualizar de django_settings_module
acordo com o seu módulo de configurações)
Feito isso, o mypy poderá inferir e verificar anotações para modelos do Django (e outros componentes).
demo$ mypy .
Success: no issues found in 5 source files
Aqui está um exemplo do uso em uma exibição pequena:
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()})
Mais uma vez, mypy está satisfeito com as anotações fornecidas:
demo$ mypy .
Success: no issues found in 7 source files
Na mesma nota, também está disponível um pacote para o Django Rest Framework: djangorestframework-stubs .