Wagtail 页面中的字段权限
Posted
技术标签:
【中文标题】Wagtail 页面中的字段权限【英文标题】:Permission for field in Wagtail Page 【发布时间】:2018-12-31 01:55:12 【问题描述】:如何将权限应用于 Wagtail 页面的各个字段? 假设我们有一个这样的页面:
class HomePage(Page):
body = RichTextField(blank=True)
content_panels = Page.content_panels + [
FieldPanel('body', classname="full"),
]
应该允许每个人编辑标题 - 但只有具有特定权限的用户才能更改正文。
【问题讨论】:
【参考方案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
显然,这是非常时髦和脆弱的。但这是我能找到的唯一解决方案。
【讨论】:
出于好奇,get_current_request()
函数是从哪里来的?
@user2415992 我使用 django-crequest 库的一个分支。它提供了一个中间件,用于存储当前请求的线程本地值。 get_current_request()
函数是我编写的一个实用程序,它可以更直接地从 crequest 的中间件中检索当前请求。以上是关于Wagtail 页面中的字段权限的主要内容,如果未能解决你的问题,请参考以下文章