etn*_*n03 4 python django mypy
我有以下 Django 视图:
@login_required
def view(request: HttpRequest) -> HttpResponse:
if not request.user.some_attribute:
return redirect("somewhere")
return render(request, "template_name")
Run Code Online (Sandbox Code Playgroud)
以及一个User具有属性 的自定义模型some_attribute。
我用mypy这个来强制类型检查mypy.ini:
[mypy]
ignore_missing_imports = True
plugins = mypy_django_plugin.main
[mypy.plugins.django-stubs]
django_settings_module = [PROJECT NAME].settings
Run Code Online (Sandbox Code Playgroud)
但是,mypy出现以下错误:
Item "AnonymousUser" of "Union[User, AnonymousUser]" has no attribute "some_attribute"
Run Code Online (Sandbox Code Playgroud)
这是有道理的,因为匿名用户不会有该属性,但我有一个login_required装饰器,使得AnonymousUsers 不可能(它将是 a User)。
我如何告诉mypy忽略这一点,而不使用# type: ignore?
您还可以子类化HttpRequest并显式设置user子类上的字段,以将类型显式定义为User而不是默认的联合对,如下所示:
from django.http import HttpRequest
from my_user_app.models import MyUser
class AuthenticatedHttpRequest(HttpRequest):
user: MyUser
Run Code Online (Sandbox Code Playgroud)
然后,每次您想要使用login_required装饰器时,请将参数的类型提示设置request为您的子类(在本例中为AuthenticatedHttpRequest),如下所示:
@login_required
def view(request: AuthenticatedHttpRequest) -> HttpResponse:
if not request.user.some_attribute:
return redirect("somewhere")
return render(request, "template_name")
Run Code Online (Sandbox Code Playgroud)
django-stubs此方法在自述文件中被指定为推荐方法,显然您正在使用该方法来获取mypy.