Wagtail 管理员 - 玩 url

Wagtail admin - playing with urls

我在 model.py 中用 wagtail 创建了一个名为 Regbox 的模型,也在 wagtail_hooks.py 中创建了一个名为 RegboxModelAdmin 的模型。 Wagtail 管理员在 wagtail 侧栏菜单中包含项目 Regbox。然后我以编程方式创建了一个新集合,一个具有添加、编辑、删除 Regbox 权限的新组,并且该组在注册后分配给新用户。新用户可以添加(编辑和删除)新的 Regbox(模型 Regbox 具有 forein key 用户)并且这个新用户只能在 wagtail admin 中看到他自己的 regboxes(我使用了查询集过滤器,以便超级用户可以看到 wagtail admin 和当前的所有 regboxes用户只能使用他自己的 regboxes)。但是如果这个新用户在他的浏览器中使用 urls,他也可以看到其他的 regboxes(不仅仅是他自己的 regboxes)。他只需将 url 从例如 /regbox/edit/5/ 更改为 /regbox/edit/8/ 并且他可以看到此页面,尽管此 page/regbox 属于另一个用户(此处需要权限被拒绝) .有人可以告诉我如何在 wagtail 管理员中执行此操作,以便任何用户只能看到他自己的 regbox 页面吗?谢谢

Django(以及 Wagtail 的扩展名)中的权限是按模型处理的,而不是按实例处理的。因此,向用户授予 Regbox 的编辑权限将允许 him/her 编辑该模型的每个实例。 Wagtail 中有一些例外(例如 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 助手 class 并定义了 inspecteditdelete 权限的方法,首先检查用户是否是所有者(这已经是它自己方法的提取器),然后调用 super 来进行原始权限检查。对 super 的调用很重要,因此如果用户不是所有者,它会 return false,但如果用户是所有者但没有特定权限,它也会 return false (例如,您可以创建和编辑但不能删除)。

FWIW,我认为您正在使用正确的机制通过过滤 queryset 来过滤列表视图,所以不要更改那里的任何内容。