如何让mymyy识别login_required装饰器?



我有如下的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?

您还可以创建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")

这个方法在django-stubs自述文件中被指定为推荐的方法,显然你正在使用它来为mypy提供Django骨架。

我相信将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")

相关内容

  • 没有找到相关文章

最新更新