如何让mypy识别登录所需的装饰器?

2024-05-17 10:18:12 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下Django观点:

@login_required
def view(request: HttpRequest) -> HttpResponse:
    if not request.user.some_attribute:
        return redirect("somewhere")
    return render(request, "template_name")

以及具有属性some_attribute的自定义User模型

我使用mypy强制执行类型检查,使用此mypy.ini

[mypy]
ignore_missing_imports = True
plugins = mypy_django_plugin.main

[mypy.plugins.django-stubs]
django_settings_module = [PROJECT NAME].settings

但是,mypy错误如下:

Item "AnonymousUser" of "Union[User, AnonymousUser]" has no attribute "some_attribute"

这是有意义的,因为匿名用户没有这个属性,但我有一个login_required装饰器,使得AnonymousUser不可能(这将是一个User

我如何告诉mypy忽略这个,而不使用# type: ignore


Tags: djangoreturn属性settingsrequestrequiredpluginslogin
2条回答

我认为将request.user转换为所需类型应该可以:

from typing import cast

@login_required
def view(request: HttpRequest) -> HttpResponse:
    request.user = cast(User, request.user)
    if not request.user.some_attribute:
        return redirect("somewhere")
    return render(request, "template_name")

您还可以将HttpRequest子类化,并显式地将子类上的user字段设置为将类型显式定义为User,而不是默认的联合对,如下所示:

from django.http import HttpRequest
from my_user_app.models import MyUser

class AuthenticatedHttpRequest(HttpRequest):
    user: MyUser

然后,每当您想要使用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")

此方法在^{} readme file中指定为推荐的方法,显然您正在使用该方法为mypy获取Django骨骼

相关问题 更多 >