英文:
Django: Unable to Apply Function View Decorator to Class Based View
问题
我正在从常规函数视图迁移到基于类的视图。其中一件事我无法迁移的是我使用的装饰器。有一个装饰器检查当前用户的凭证是否有效,然后执行被装饰的函数:
def custom_auth(function):
@wraps(function)
def wrap(request, *args, **kwargs):
# 用于验证用户是否具有正确凭证的逻辑
# 获取访问该函数的用户
user_object = User.objects.get(username=request_username)
# 尝试执行被装饰的函数。如果失败,重定向到上一页并显示错误弹窗
try:
return function(request, user=user_object, *args, **kwargs)
except:
# 显示弹窗的逻辑
以前,我只需这样装饰我的函数:
@custom_auth
def view(request, *args, **kwargs):
# 视图逻辑
然而,当我尝试以相同的方式应用到我的基于类的视图时,出现了一个错误,错误信息为__init__()接受1个位置参数,但给定了2个:user='username',view='cbvview'
。
@custom_auth
class CBV(View):
def get(self, request, *args, **kwargs):
# 获取请求逻辑
我知道这不是应用装饰器的方式,所以我尝试了不同的方法。无论是将装饰器添加到urls.py
中,添加@method_decorator(custom_auth, name="dispatch")
或者简单地覆盖dispatch
方法,但都无法正常工作。它们都给我同样的错误。
可能的问题是什么?也许我应该使用自定义混入(mixin)?
英文:
I'm migrating from regular function based views, to class based views. One of the things that I couldn't migrate were the decorators I used. The decorator in question checks if the credentials of the current user are valid and then executes the decorated function:
def custom_auth(function):
@wraps(function)
def wrap(request, *args, **kwargs):
# Logic for validating if user has correct credentials
# Fetches the user that accessed the function
user_object = User.objects.get(username=request_username)
# Try to execute the decorated function. If it fails, redirect
# to previous page and show an error popup
try:
return function(request, user=user_object, *args, **kwargs)
except:
# Logic for displaying the popup
Previously I could just decorate my function by doing
@custom_auth
def view(request, *args, **kwargs):
# View logic
However, when I try to apply it to my class based view in the same way, I get an error saying __init__() takes 1 positional argument but 2 were given: user='username', view='cbvview'
@custom_auth
class CBV(View):
def get(self, request, *args, **kwargs):
# Get request logic
I know that this is not the way you are supposed to apply the decorator, so I tried with different approaches. Either adding the decorator to urls.py
, adding the @method_decorator(custom_auth, name="dispatch")
or simply overriding the dispatch method, but none of them work. All of them give me the same error.
What could be the issue? Maybe I should use a custom mixin instead?
答案1
得分: 1
来自Django文档的代码链接:https://docs.djangoproject.com/en/4.1/topics/class-based-views/intro/
@method_decorator(login_required, name='dispatch')
class ProtectedView(TemplateView):
template_name = 'secret.html'
无需在装饰器的函数调用中添加用户,它已经包含在请求中。
英文:
from django docs https://docs.djangoproject.com/en/4.1/topics/class-based-views/intro/
@method_decorator(login_required, name='dispatch')
class ProtectedView(TemplateView):
template_name = 'secret.html'
and there is no need to add the user to the function call in the decorator. It is already in the request
答案2
得分: 1
Use @method_decorator
如下所示:
from django.utils.decorators import method_decorator
@method_decorator(custom_auth, name="dispatch")
class CBV(View):
def get(self, request, *args, **kwargs):
...
编辑:
尝试创建自己的mixin类并继承它以在CBV
类中使用,如下所示:
class CustomAuthMixin:
def dispatch(self, request, *args, **kwargs):
# 验证用户是否具有正确的凭据的逻辑
# 获取访问函数的用户
user_instance = User.objects.get(username=request_username)
# 尝试执行已装饰的函数。如果失败,重定向到上一页并显示错误弹出窗口
try:
return super().dispatch(request, user=user_instance, *args, **kwargs)
except:
# 显示弹出窗口的逻辑
class CBV(CustomAuthMixin, View):
def get(self, request, *args, **kwargs):
# 获取请求的逻辑
英文:
Use @method_decorator
like following:
from django.utils.decorators import method_decorator
@method_decorator(custom_auth,name="dispatch")
class CBV(View):
def get(self, request, *args, **kwargs):
...
Edit:
Try to make your own mixin as class and inherit it to be used in CBV
class so:
class CustomAuthMixin:
def dispatch(self, request, *args, **kwargs):
# Logic for validating if user has correct credentials
# Fetches the user that accessed the function
user_instance = User.objects.get(username=request_username)
# Try to execute the decorated function. If it fails, redirect
# to previous page and show an error popup
try:
return super().dispatch(request, user=user_instance, *args, **kwargs)
except:
# Logic for displaying the popup
class CBV(CustomAuthMixin, View):
def get(self, request, *args, **kwargs):
# Get request logic
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论