ggl*_*ses 5 python generics django
我有一个名为的模型,Post并有一个字段owner(外键User).当然,只有业主可以update或delete自己的帖子.
话虽这么说,我login_required在视图中使用装饰器来确保用户登录但是,我还需要确保用户尝试update/ delete问题是owner.
当我使用Django:Generic Editing Views时,文档说我需要使用Django:UserPassesTestMixin.
将对update和delete视图进行此验证.干,这是怎么回事?我应该创建一个名为的类TestUserOwnerOfPost并创建一个test_func(),然后让它update和delete视图继承吗?
因为这是我尝试过但没有用的,代码如下:
from django.views.generic.edit import UpdateView
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import UserPassesTestMixin
class TestUserOwnerOfPost(UserPassesTestMixin):
def test_func(self):
return self.request.user == self.post.owner
class EditPost(UpdateView, TestUserOwnerOfPost):
model = Post
@method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super(EditPost, self).dispatch(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)
使用上面的代码,系统中的每个登录用户都可以edit/ delete任何帖子.我究竟做错了什么?我错过了什么吗?谢谢.
第一个问题是你继承的类的顺序是不正确的,正如@rafalmp所说的那样.
但是,修复不能解决问题,因为UserPassesTestmixin 在运行视图之前执行测试.这意味着它不适合检查所有者self.object,因为self.object尚未设置.注意我正在使用self.object而不是self.post- 我不认为视图曾经设置过,self.post但我可能错了.
一种选择是调用self.get_object()测试功能.这有点低效,因为您的视图将获取对象两次,但在实践中它可能无关紧要.
def test_func(self):
self.object = self.get_object()
return self.request.user == self.object.owner
Run Code Online (Sandbox Code Playgroud)
另一种方法是覆盖get_queryset,将其限制为用户拥有的对象.这意味着如果用户不拥有该对象,则会收到404错误.此行为与UserPassesTestMixin将重定向到登录页面的行为不完全相同,但它可能适合您.
class OwnerQuerysetMixin(object):
def get_queryset(self):
queryset = super(OwnerQuerysetMixin, self).get_queryset()
# perhaps handle the case where user is not authenticated
queryset = queryset.filter(owner=self.request.user)
return queryset
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1391 次 |
| 最近记录: |