我在wagtail中创建了一个模型,该模型在model.py中创建了一个名为Regbox的模型,还在wagtail_hooks.py中创建了RegboxModelAdmin。 g管理员在w侧栏菜单中包括Regbox项。然后,我以编程方式创建了一个新集合,一个具有添加,编辑,删除Regbox权限的新组,该组在注册后分配给了新用户。新用户可以添加(编辑和删除)新的Regbox(模型Regbox具有forein键User),而该新用户只能在wagtail admin中看到他自己的regbox(我使用queryset过滤器,以便超级用户可以在wagtail admin和当前用户中看到所有regbox。用户仅使用自己的注册表框)。但是,如果该新用户在其浏览器中使用URL进行播放,那么他还可以看到其他注册表框(不仅是他自己的注册表框)。他可以简单地将url从/ regbox / edit / 5 /更改为/ regbox / edit / 8 /,尽管此页面/ regbox属于另一个用户,但他可以看到此页面(此处需要权限被拒绝)。有人可以建议我如何在wagtail admin中做到这一点,以便任何用户只能看到自己的regbox页面吗?谢谢
答案 0 :(得分:1)
Django(和Wagtail扩展名)中的权限是基于模型而不是每个实例处理的。因此,向用户授予Regbox
的编辑权限将允许他/她编辑该模型的每个实例。 Wa(Watail)中有一些例外(例如Page模型)。
无论如何,通过将自定义permission helper class附加到您的ModelAdmin
定义,您应该能够实现所需的功能并添加自定义权限检查。
from wagtail.contrib.modeladmin.helpers import PermissionHelper
from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register
from .models import Regbox
class RegboxPermissionHelper(PermissionHelper):
def user_is_owner(self, user, obj):
if user.pk == obj.owner:
return True
else:
return False
def user_can_inspect_obj(self, user, obj):
"""
Return a boolean to indicate whether `user` is permitted to 'inspect'
a specific `self.model` instance.
"""
return self.user_is_owner(user, obj) && super().user_can_inspect_obj(user, obj)
def user_can_edit_obj(self, user, obj):
"""
Return a boolean to indicate whether `user` is permitted to 'change'
a specific `self.model` instance.
"""
return self.user_is_owner(user, obj) && super().user_can_edit_obj(user, obj)
def user_can_delete_obj(self, user, obj):
"""
Return a boolean to indicate whether `user` is permitted to 'delete'
a specific `self.model` instance.
"""
return self.user_is_owner(user, obj) && super().user_can_delete_obj(user, obj)
class RegboxModelAdmin(ModelAdmin):
model = Regbox
permission_helper_class = RegboxPermissionHelper
modeladmin_register(RegboxModelAdmin)
如您所见,我们创建了一个新的RegboxPermissionHelper
助手类,并为inspect
,edit
和delete
权限定义了方法,这些方法首先检查用户是所有者(这已提取到其自己的方法),然后调用super进行原始权限检查。对super
的调用很重要,因此如果用户不是所有者,则返回false,但如果用户是所有者但没有特定权限,也会返回false(例如,您可以创建和编辑但不能删除)。
FWIW,我认为您正在使用正确的机制通过过滤queryset来过滤列表视图,因此请不要在此处进行任何更改。