Djangoモデルの型注釈


8

私はDjangoプロジェクトに取り組んでいます。これは新しいプロジェクトなので、Python 3.6+タイプの注釈で完全に注釈を付けたいです。モデルに注釈を付けようとしていますが、そのための適切な方法を見つけるのに苦労しています。

IntegerField例を見てみましょう。注釈を付ける方法は2つあります。

# 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には問題ありませんが、PyCharmとしてのIDEはそれを解決できず、使用された間違った型について不平を言うことがよくあります。

mypyとIDEを満足させるモデルに正しく注釈を付けるためのベストプラクティスはありますか?


3
満足のいくツールに多くの時間を費やしているように思われるので、あなたがすることは静的注釈付けのために設計された型注釈ではないということを聞いて驚くかもしれません。
クラウスD.

mypy-djangoのようなものを探していませんか?
Pedram Parsian

mypy-ジャンゴのように見えるモデルの型注釈を提供していません:github.com/machinalis/mypy-django-example/blob/master/polls/...
クレマンDenoix

@KlausD。-あなたの言っていることが理解できたかどうかわかりませんが、詳しく説明していただけますか?
ジェント

IntegerField()でこれをうまく行ったとしても、50文字のフィールドには何を計画しますか?それが一種の文字列であることを知っておくのはいいことですが、実際にはそうではありません。素朴な質問をしますが、タイプはすでにあります。あなたはそれらを基本的な型にキャストしようとしています、それは私には思えます...正確にどの問題を解決したいですか?それは非常に難しい問題です... Rustがそれとどれだけ進んでいるか見てください。
Tim Richardson

回答:


8

Djangoモデル(およびその他のコンポーネント)は、背後に多くの魔法があるため、注釈を付けるのが困難です。良いニュースは、クールな開発者のグループがすでに私たちのために大変な作業を行っていることです。

django- stubsは、Djangoに静的型と型推論を提供する一連のスタブとmypyプラグインを提供します。

たとえば、次のモデルがあるとします。

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も利用できます。


私は実際にこれを見つけましたが、間違って使用しました。前進に役立つ詳細な回答をありがとうございます。
Djent
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.