我在理解新的 CBV 的工作原理时遇到了一些麻烦。我的问题是,我需要登录所有视图,其中一些视图需要特定权限。在基于函数的视图中,我使用 @permission_required() 和视图中的 login_required 属性来执行此操作,但我不知道如何在新视图上执行此操作。django 文档中是否有一些部分对此进行了解释?我什么也没找到。我的代码有什么问题?
我尝试使用@method_decorator,但它回复“ TypeError at /spaces/prueba/_wrapped_view() 需要至少 1 个参数(给定 0) ”
这是代码(GPL):
from django.utils.decorators import method_decorator from django.contrib.auth.decorators import login_required, permission_required class ViewSpaceIndex(DetailView): """ Show the index page of a space. Get various extra contexts to get the information for that space. The get_object method searches in the user 'spaces' field if the current space is allowed, if not, he is redirected to a 'nor allowed' page. """ context_object_name = 'get_place' template_name = 'spaces/space_index.html' @method_decorator(login_required) def get_object(self): space_name = self.kwargs['space_name'] for i in self.request.user.profile.spaces.all(): if i.url == space_name: return get_object_or_404(Space, url = space_name) self.template_name = 'not_allowed.html' return get_object_or_404(Space, url = space_name) # Get extra context data def get_context_data(self, **kwargs): context = super(ViewSpaceIndex, self).get_context_data(**kwargs) place = get_object_or_404(Space, url=self.kwargs['space_name']) context['entities'] = Entity.objects.filter(space=place.id) context['documents'] = Document.objects.filter(space=place.id) context['proposals'] = Proposal.objects.filter(space=place.id).order_by('-pub_date') context['publication'] = Post.objects.filter(post_space=place.id).order_by('-post_pubdate') return context
CBV 文档中列出了一些策略:
urls.py
based-views/intro/#decorating-in-urlconf) )中实例化视图时装饰视图
urlpatterns = [ path('view/',login_required(ViewSpaceIndex.as_view(..)), ... ]
urls.py装饰器是基于每个实例应用的,因此您可以根据需要在不同的路由中添加或删除它。
based-views/intro/#decorating-the-class))
有两种方法可以做到这一点:
适用method_decorator于您的 CBV 调度方法,例如,
method_decorator
from django.utils.decorators import method_decorator
from django.contrib.auth.decorators import login_required
@method_decorator(login_required, name=’dispatch’) class ViewSpaceIndex(TemplateView): template_name = ‘secret.html’
如果您使用的是 Django < 1.9(您不应该这样做,它不再受支持),则您不能method_decorator在该类上使用,因此您必须dispatch手动覆盖该方法:
dispatch
class ViewSpaceIndex(TemplateView): @method_decorator(login_required) def dispatch(self, *args, **kwargs): return super(ViewSpaceIndex, self).dispatch(*args, **kwargs)
使用像django.contrib.auth.mixins.LoginRequiredMixin这样的 mixin ,在此处的其他答案中得到了很好的概述:
from django.contrib.auth.mixins import LoginRequiredMixin
class MyView(LoginRequiredMixin, View):
login_url = '/login/' redirect_field_name = 'redirect_to'
确保将 mixin 类放在继承列表的第一个位置(因此 Python 的方法解析顺序算法会选择正确的东西)。
您获得 a 的原因TypeError在文档中进行了解释:
TypeError
注意:method_decorator 将 args 和 *kwargs 作为参数传递给类上的装饰方法。如果您的方法不接受一组兼容的参数,它将引发 TypeError 异常。