我在理解新CBV如何工作方面遇到了一些麻烦 . 我的问题是,我需要在所有视图中登录,在其中一些视图中需要登录特定权限 . 在基于函数的视图中,我使用@permission_required()和视图中的login_required属性执行此操作,但我不知道如何在新视图上执行此操作 . django文档中是否有一些部分解释了这一点?我没找到任何东西 . 我的代码有什么问题?
我试图使用@method_decorator,但它回复“ TypeError at /spaces/prueba/ _wrapped_view() takes at least 1 argument (0 given) ”
这是代码(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
11 回答
在我的代码中,我编写了这个适配器来使成员函数适应非成员函数:
您可以像这样简单地使用它:
the CBV docs中列出了一些策略:
Add the decorator in your urls.py route,例如
login_required(ViewSpaceIndex.as_view(..))
Decorate your CBV's dispatch method with a method_decorator例如,
在Django 1.9之前,你不能在类上使用
method_decorator
,所以你必须覆盖dispatch
方法:您收到
TypeError
的原因在文档中有解释:如果它是大多数页面要求用户登录的站点,则可以使用中间件强制登录所有视图,除了一些特别标记的视图 .
Pre Django 1.10 middleware.py:
views.py:
您不想包装的第三方视图可以在设置中排除:
settings.py:
这是我的方法,我创建一个受保护的mixin(这保存在我的mixin库中):
只要您想要保护视图,您只需添加适当的mixin:
Just make sure that your mixin is first.
Update: 我在2011年发布了这个版本,从版本1.9开始,Django现在包括这个和其他有用的mixin(AccessMixin,PermissionRequiredMixin,UserPassesTestMixin)作为标准!
使用Django Braces . 它提供了许多易于获得的有用mixin . 它有漂亮的文档 . 试试看 .
您甚至可以创建自定义mixins .
http://django-braces.readthedocs.org/en/v1.4.0/
示例代码:
我意识到这个线程有点陈旧,但无论如何这里是我的两分钱 .
使用以下代码:
我们现在有办法修补装饰器,因此它将变得多功能化 . 这实际上意味着当应用于常规视图装饰器时,如下所示:
这个装饰器在按原来的方式使用时仍然可以工作:
但如果这样使用也会正常工作:
在我最近遇到的几个案例中,这似乎工作得很好,包括这个现实世界的例子:
编写ajax_view函数是为了修改(基于函数的)视图,因此只要非ajax调用访问此视图,就会引发404错误 . 通过简单地将补丁函数应用为装饰器,该装饰器也被设置为在基于类的视图中工作
这是非常容易的django> 1.9来支持
PermissionRequiredMixin
和LoginRequiredMixin
只需从身份验证中导入即可
views.py
有关详细信息,请阅读Authorization in django
我根据Josh的解决方案做了那个修复
样品用法:
如果您正在执行需要各种权限测试的项目,则可以继承此类 .
这是使用基于类的装饰器的替代方法:
然后可以像这样简单地使用它:
对于那些使用 Django >= 1.9 的人来说,它已作为AccessMixin,LoginRequiredMixin,PermissionRequiredMixin和UserPassesTestMixin包含在
django.contrib.auth.mixins
中 .因此,要将LoginRequired应用于CBV(例如
DetailView
):记住GCBV Mixin顺序也很好:Mixins必须在 left 侧,基本视图类必须在 right 侧 . 如果订单不同,您可能会遇到破碎和不可预测的结果 .