我在理解新的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
发布于 2011-05-20 16:42:20
the CBV docs中列出了一些策略
在urls.py
(docs)中实例化视图时装饰视图
urlpatterns = [
path('view/',login_required(ViewSpaceIndex.as_view(..)),
...
]
装饰器是基于每个实例应用的,因此您可以根据需要在不同的urls.py
路由中添加或删除它。
装饰您的类,以便包装视图的每个实例(docs)
有两种方法可以完成此操作:
method_decorator
应用于您的CBV派单方法,例如,从django.utils.decorators导入method_decorator @method_decorator(login_required,name='dispatch')类ViewSpaceIndex(TemplateView):template_name =django.utils.decorators
如果您使用的是Django < 1.9 (您不应该使用,它不再受支持),则不能在类上使用method_decorator
,因此您必须手动覆盖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,MyView):login_url =‘/MyView/’redirect_field_name =LoginRequiredMixin
确保将mixin类放在继承列表的第一位(以便Python的Method Resolution Order algorithm选择正确的内容)。
文档中解释了你获得TypeError
的原因:
注意: method_decorator将*args和**kwargs作为参数传递给类上的修饰方法。如果您的方法不接受一组兼容的参数,它将引发TypeError异常。
发布于 2011-06-23 21:51:53
这是我的方法,我创建了一个受保护的混入(它保存在我的混入库中):
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
class LoginRequiredMixin(object):
@method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
return super(LoginRequiredMixin, self).dispatch(request, *args, **kwargs)
当你想要保护一个视图时,你只需添加适当的混合:
class SomeProtectedViewView(LoginRequiredMixin, TemplateView):
template_name = 'index.html'
只要确保你的混入是第一位就行了。
更新: Django我在2011年发布了这篇文章,从1.9Django版本开始,现在包括了这个和其他有用的 (AccessMixin,PermissionRequiredMixin,UserPassesTestMixin)作为标准!
发布于 2011-12-08 18:13:28
这里有一个使用基于类的装饰器的替代方案:
from django.utils.decorators import method_decorator
def class_view_decorator(function_decorator):
"""Convert a function based decorator into a class based decorator usable
on class based Views.
Can't subclass the `View` as it breaks inheritance (super in particular),
so we monkey-patch instead.
"""
def simple_decorator(View):
View.dispatch = method_decorator(function_decorator)(View.dispatch)
return View
return simple_decorator
然后可以像这样简单地使用它:
@class_view_decorator(login_required)
class MyView(View):
# this view now decorated
https://stackoverflow.com/questions/6069070
复制相似问题