我不习惯使用基于类的视图,但我知道他们的特权,所以我强迫自己开始更频繁地使用它们。
这个视图接收路径参数:manage/:id
来管理特定实体。
class MyView(TemplateView):
template_name = '...'
def get_context_data(self, **kwargs):
context = super(MyView, self).get_context_data(**kwargs)
context['entity'] = get_object_or_404(Entity, pk=self.args[0])
return context
Entity
包括执行特殊操作的授权用户列表。此视图MyView
是其中一项特殊操作。
我尝试为视图制作一个装饰器,但它需要先找到Entity
,所以我不知道如何解决这个问题。
现在,我有一个check_permission(request, entity)
函数,用于检查当前用户是否是这些授权用户之一。
我的问题是我应该在基于类的视图中调用此函数,例如MyView
这些视图中的任何一个被视为“特殊操作”吗?
我应该只从get_context_data()
拨打电话吗?
答案 0 :(得分:3)
将其放入dispatch()。它看起来像这样:
class MyView(TemplateView):
template_name = '...'
def dispatch(self, request, *args, **kwargs):
entity = get_object_or_404(Entity, pk=args[0])
if not check_permission(request, entity):
raise Http404
return super(MyView, self).dispatch(request, *args, **kwargs)
答案 1 :(得分:1)
您可以检查dispatch
中的权限,因为yedpodtrzitko已经说过了。我认为将它放在一个可以放在你的观点上的mixin中也是一个好主意。
以下是一个例子:
from django.core.exceptions import PermissionDenied
class ViewPermissionsMixin(object):
"""Base class for all custom permission mixins to inherit from"""
def has_permissions(self):
return True
def dispatch(self, request, *args, **kwargs):
if not self.has_permissions():
raise PermissionDenied
return super(ViewPermissionsMixin, self).dispatch(
request, *args, **kwargs)
class MyCustomPermissionMixin(ViewPermissionsMixin):
def has_permissions(self):
# here you will have access to both
# self.get_object() and self.request.user
return self.request.user in self.get_object().special_list_of_people
现在你可以在你的观点上抛出MyCustomPermissionMixin
:
class MyView(MyCustomPermissionMixin, TemplateView):
# ...
在您的情况下,由于您使用的是TemplateView
,因此您还应该创建一个get_object()
方法来返回您要处理的对象。默认情况下,模板视图没有此方法。
最后,只想说一旦你学会了如何使用它们,你就会喜欢Django的基于类的观点。
答案 2 :(得分:0)
看看Django Braces,这是一组围绕权限设计的可靠的mixin。
您处理权限的具体方式在很大程度上取决于实施。我已经在dispatch()中完成了它,之前是Braces的方式,但如果它是特定于对象或查询集的,我将在实际的get_object或get_queryset方法中作为DetailView的一部分进行。
例如,如果您有与实体关联的创建者,则可以覆盖get_object
以检查当前登录用户是实体的创建者。
class EntityView(LoginRequiredMixin, DetailView):
model = Thing
def get_object(self, **kwargs):
return Entity.objects.get_object_or_404(
pk=kwargs['entity_id'],
creator=self.request.user
)
注意:LoginRequiredMixin是Braces的一部分。非常光滑。