是否有 Django 视图装饰器来检查不假设输入是用户的条件?
Is there Django view decorator to check a condition that doesn't assume the input is a User?
我有一个非常简单的 Django 装饰器 my_decorator1
,看起来像这样:
def my_decorator_1(function):
@wraps(function)
def decorator(self, *args, **kwargs):
self.my_val = random.randint(0,1)
return function(self, *args, **kwargs)
return decorator
我的 Django APIView 看起来像这样:
class MyApiView(views.APIView):
@what_decorator_goes_here
@my_decorator_1
def post(self, request, *args, **kwargs):
"""
Blah Blah Blah. The rest is snipped out for brevity.
"""
现在我想要装饰器授予对 MyApiView 的访问权限 iff self.my_val == 1。否则它应该给出一个权限被拒绝错误 (403)。我该怎么做?我需要它来替换 @what_decorator_goes_here
。这在工作流程中并不少见。
难道没有一个预先编写的 django 装饰器可以用于此目的吗?我见过的两个similar ones是@user_passes_test
和@permission_required
。但是,它们都不对 self
参数进行操作。第一个假设输入是 User
,第二个假设输入不同。
只是return一个HttpResponseForbidden
响应对象:
from django.http import HttpResponseForbidden
def what_decorator_goes_here(function):
@wraps(function)
def check_value(self, *args, **kwargs):
if getattr(self, 'my_val', None) == 1:
return function(self, *args, **kwargs)
else:
return HttpResponseForbidden()
return check_value
或更复杂:
def allow_if_view_value(attr_name, target_value):
def decorator(function):
@wraps(function)
def check_value(self, *args, **kwargs):
if getattr(self, attr_name, None) == target_value:
return function(self, *args, **kwargs)
else:
return HttpResponseForbidden()
return check_value
return decorator
@allow_if_view_value('my_val', 1)
[...]
虽然我必须说,但我不太喜欢使用装饰器来完成此操作,而不是使用相应地分派请求的通用视图基础 class。
我认为您应该能够从装饰器本身引发 PermissionDenied 异常。
from django.core.exceptions import PermissionDenied
def my_decorator_1(function):
@wraps(function)
def decorator(self, *args, **kwargs):
self.my_val = random.randint(0,1)
if self.my_val == 1:
raise PermissionDenied
return function(self, *args, **kwargs)
return decorator
我认为这就是您提到的装饰器的工作方式。然后 Django 请求管道将拾取异常并相应地处理它。
我有一个非常简单的 Django 装饰器 my_decorator1
,看起来像这样:
def my_decorator_1(function):
@wraps(function)
def decorator(self, *args, **kwargs):
self.my_val = random.randint(0,1)
return function(self, *args, **kwargs)
return decorator
我的 Django APIView 看起来像这样:
class MyApiView(views.APIView):
@what_decorator_goes_here
@my_decorator_1
def post(self, request, *args, **kwargs):
"""
Blah Blah Blah. The rest is snipped out for brevity.
"""
现在我想要装饰器授予对 MyApiView 的访问权限 iff self.my_val == 1。否则它应该给出一个权限被拒绝错误 (403)。我该怎么做?我需要它来替换 @what_decorator_goes_here
。这在工作流程中并不少见。
难道没有一个预先编写的 django 装饰器可以用于此目的吗?我见过的两个similar ones是@user_passes_test
和@permission_required
。但是,它们都不对 self
参数进行操作。第一个假设输入是 User
,第二个假设输入不同。
只是return一个HttpResponseForbidden
响应对象:
from django.http import HttpResponseForbidden
def what_decorator_goes_here(function):
@wraps(function)
def check_value(self, *args, **kwargs):
if getattr(self, 'my_val', None) == 1:
return function(self, *args, **kwargs)
else:
return HttpResponseForbidden()
return check_value
或更复杂:
def allow_if_view_value(attr_name, target_value):
def decorator(function):
@wraps(function)
def check_value(self, *args, **kwargs):
if getattr(self, attr_name, None) == target_value:
return function(self, *args, **kwargs)
else:
return HttpResponseForbidden()
return check_value
return decorator
@allow_if_view_value('my_val', 1)
[...]
虽然我必须说,但我不太喜欢使用装饰器来完成此操作,而不是使用相应地分派请求的通用视图基础 class。
我认为您应该能够从装饰器本身引发 PermissionDenied 异常。
from django.core.exceptions import PermissionDenied
def my_decorator_1(function):
@wraps(function)
def decorator(self, *args, **kwargs):
self.my_val = random.randint(0,1)
if self.my_val == 1:
raise PermissionDenied
return function(self, *args, **kwargs)
return decorator
我认为这就是您提到的装饰器的工作方式。然后 Django 请求管道将拾取异常并相应地处理它。