如何将权限应用于Wagtail页面的各个字段? 假设我们有一个这样的页面:
class HomePage(Page):
body = RichTextField(blank=True)
content_panels = Page.content_panels + [
FieldPanel('body', classname="full"),
]
每个人都可以编辑标题-但只有具有一定权限的用户才可以更改正文。
答案 0 :(得分:1)
我意识到现在这是一个非常老的问题,但是以防万一将来有人遇到它,这就是我的代码店在Wagtail 2.3中是如何做到的。在更高版本中它可能会或可能不会起作用。
将以下内容添加到您编写的Page子类中:
panels = [
...
MultiFieldPanel(
[
FieldPanel('display_locations', widget=forms.CheckboxSelectMultiple),
StreamFieldPanel('assets'),
],
heading='Admin-only Fields',
# NOTE: The 'admin-only' class is how EventPage.get_edit_handler() identifies this MultiFieldPanel.
classname='collapsible admin-only'
),
...
]
class Meta:
verbose_name = 'Event'
verbose_name_plural = 'Events'
ordering = ['start_date', 'title']
permissions = (
('can_access_admin_fields', 'Can access Event Admin fields'),
)
@classmethod
def get_edit_handler(cls):
"""
We override this method (which is added to the Page class in wagtail.admin.edit_handlers) in order to enforce
our custom field-level permissions.
"""
# Do the same thing that wagtail.admin.edit_handlers.get_edit_handler() would do...
bound_handler = cls.edit_handler.bind_to_model(cls)
# ... then enforce admin-only field permissions on the result.
current_request = get_current_request()
# This method gets called during certain manage.py commands, so we need to be able to gracefully fail if there
# is no current request. Thus, if there is no current request, the admin-only fields are removed.
if current_request is None or not current_request.user.has_perm('calendar_app.can_access_admin_fields'):
# We know for sure that bound_handler.children[0].children is the list of Panels in the Content tab.
# We must search through that list to find the admin-only MultiFieldPanel, and remove it.
# The [:] gets us a copy of the list, so altering the original doesn't change what we're looping over.
for child in bound_handler.children[0].children[:]:
if 'admin-only' in child.classname:
bound_handler.children[0].children.remove(child)
break
return bound_handler
这显然很时髦且脆弱。但这是我能找到的唯一解决方案。