Django:使用基于类的视图基于对象的属性进行身份验证 [英] Django: authenticate based on an object's properties using class-based views
问题描述
让我们说我的应用程序就像一个论坛,但是每个帖子都有一群人可以看到。
Let's say my app is like a forum, but that each post has a group of people which may see it.
SecretPost(Model):
can_see = myapp.main.models.GroupOfUsers()
I想要写一个视图来限制用户对这些帖子的访问,我更喜欢使用装饰器,因为这就是我一直在其他地方处理访问控制的方式。
I want to write a view which restricts users' access to these posts, and I'd prefer to use decorators, since that's how I've been handling access control everywhere else.
SecretPostView(DetailView):
"""Can only be seen by members of its group"""
@method_decorator(part_of_its_group)
def dispatch(self, request, *args, **kwargs):
return super(SecretPostView, self).dispatch(request, *args, **kwargs)
但是当调用 dispatch()
时,我对该对象一无所知。
But when dispatch()
is called, I don't know anything about the object. Is there a good/idiomatic way to restrict user access after the object has already been retrieved?
推荐答案
您可以访问 self
在方法装饰器中,因此您 do 可以访问调用 self.get_object()
。
You can access self
inside the method decorator, so you do have access to the current object calling self.get_object()
.
无论如何,如果仅在通用视图上使用此行为,则最好创建一个实现 dispatch
方法(也可以是 get_object
方法)并在那里进行检查(例如,由于idk如何定义组,因此需要一些想象力,也许您正在使用django.contrib.auth组):
Anyway, if you are only using this behavior on generic views, you're probably better off creating a mixin that implement the dispatch
method (or could be the get_object
method) and does the check there, for example (using a little of imagination since idk how your groups are defined, maybe you are using django.contrib.auth groups):
class GroupRestrictionMixin(object):
group_field = 'group'
def dispatch(request, *args, **kwargs):
self.request = request
self.args = args
self.kwargs = kwargs
obj_group = getattr(self.get_object(), self.group_field)
user_groups = request.user.groups
if obj_group not in user_groups:
raise PermissionDenied
return super(GroupRestrictionMixin, self).dispatch(request, *args, **kwargs)
然后,您可以使用以下方法创建需要该行为的任何视图您的mixin:
Then you can create any view that needs that behavior using your mixin:
class SecretPostView(GroupRestrictionMixin, DetailView):
pass
Idk,如果您将其称为惯用语言,但这是使它保持简单和可重用性的简便方法。
Idk if it's what you would call "idiomatic", but that's the easier way that comes to mind to keep it simple and reusable.
编辑:必须在此处设置请求,参数和参数,以便 get_object
方法可以访问它们。它有点难看(您必须在基本 dispatch
方法上重复一些代码),但仍然可以使用:F
the request, args and kwargs must be setted here so the get_object
method haves access to them. It gets a little uglier (you gotta repeat some code that's on the base dispatch
method), but still works :F
这篇关于Django:使用基于类的视图基于对象的属性进行身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!