如何过滤 wagtail 管理中的页面列表,以便编辑者只能看到他们创建的页面?
How to filter page lists in the wagtail admin so editors only see pages they created?
我正在创建一个 wagtail 网站,用户可以在其中注册、登录到 wagtail 管理员并编写要发布的文章页面。 wagtail admin 中是否有拦截和过滤数据的钩子或可能的方法,以便用户只能看到他们自己创建的文章页面?
到目前为止,我已经使用 django-allauth 设置了用户注册,并且用户能够成功登录。一旦注册,user_signed_up 接收者就会触发,用户将被分配到 'Author' 角色。在管理员中,作者只能添加文章。 Articles 是一个带有文章索引页和文章页(基本上是博客和博客索引页)的应用程序。一旦他们登录,他们唯一看到的就是左侧的“页面”选项卡,单击该选项卡会将他们带到 'Articles' 列表。他们可以在这里添加 'Article' 页面并查看他们目前创建的文章。
这也是我的问题所在。在文章列表页面,用户可以看到站点上所有用户创建的所有文章。他们只能编辑自己的,这很好,但最终会有数百篇来自其他用户的文章。有没有办法在 'Articles' 数据显示之前拦截它并由当前用户过滤?
拦截此数据的结果将使登录到 wagtail 管理员的每个用户只知道他们创建的文章页面。
非常感谢,这是我第一次使用 Wagtail,到目前为止我很喜欢它。
我发现了这个问题的两种不同的解决方案。
- 实施 ModelAdmin 以创建模型的自定义页面列表视图。这使您可以创建一个全新的管理菜单项和相应的列表视图。此方法涉及更多,但提供更多控制。
- 按组对文件管理器结果实施 construct_explorer_page_queryset 管理挂钩。此方法实施起来快速且容易,并允许您使用 Wagtails 现有的页面浏览器。
我将介绍我是如何处理上述每种方法的。两者都有效,这是决定我是否更喜欢使用页面浏览器中内置的 Wagtails 的问题。
方法一:ModelAdmin
ModelAdmin.get_queryset() 的使用和其他有用的方法在 Wagtail 文档中找到 here。
根据 Wagtail 文档中的 this page,我将 ModelAdmin 添加到 INSTALLED_APPS:
# base.py settings
INSTALLED_APPS = [
...
'wagtail.contrib.modeladmin',
]
然后我在我的 'article' 应用程序中创建了一个名为 wagtail_hooks.py 的文件。在该文件中,我添加了代码以在管理员中创建我的文章列表页面:
# wagtail_hooks.py
from wagtail.contrib.modeladmin.options import (ModelAdmin, modeladmin_register)
from .models import Article
class ArticleAdmin(ModelAdmin):
model = Article
menu_label = 'Articles'
menu_icon = 'doc-full-inverse'
menu_order = 000
add_to_settings_menu = False
exclude_from_explorer = False
list_display = ('title', 'owner')
search_fields = ('title', 'owner')
def get_queryset(self, request):
qs = super().get_queryset(request)
#only show articles from the current user
return qs.filter(owner=request.user)
modeladmin_register(ArticleAdmin)
这里的关键是实现 ModelAdmin.get_queryset() 让我过滤文章所有者。
您可能还想删除页面浏览器菜单项,因为它有点多余。我还建议也实施下面的方法 2。即使您删除了页面浏览器菜单项,用户也可能通过直接在浏览器中输入 URL 来到达那里。如果他们这样做,实施方法 2 将确保看不到其他用户创作的内容。
方法二:construct_explorer_page_queryset @hooks
Wagtail 文档中的 hook 信息 - construct_explorer_page_queryset
还引用了这篇 Google 网上论坛文章 - https://groups.google.com/forum/#!topic/wagtail/10tcq8PB8io
在我上面创建的同一个 wagtail_hooks.py 文件中,我添加了以下代码:
@hooks.register('construct_explorer_page_queryset')
def show_authors_only_their_articles(parent_page, pages, request):
user_group = request.user.groups.filter(name='Author').exists()
if user_group:
pages = pages.filter(owner=request.user)
return pages
第二种方法就是这些。
@Pahikua 请注意,方法 2 只是将页面从列表中隐藏起来,并不能防止页面被编辑和删除。在您的情况下,这意味着 Author1 可以像 pages/id/edit/ 这样打开 url,其中 id 是 Author2 拥有的页面的 ID 并对其进行编辑。
要避免这种情况,您必须添加 before_edit_page 和 before_delete_page 挂钩。像这样:
@hooks.register('before_edit_page')
def before_edit_page(request, page):
user_group = request.user.groups.filter(name='Author').exists()
if user_group and page.owner != request.user:
raise PermissionDenied
感谢@Pahikua 和@Igor Margitich。我能够将他们的答案组合成一个漂亮的排列,这正是我想要的。
- 按照@Pahikua 在他的方法 1 中的建议,为文章(或您希望作者能够使用的任何其他模型)创建一个管理菜单项。这将为作者提供快速访问其内容的快捷方式(甚至可以从此处添加内容)。
- 我没有删除 Page Explorer 管理菜单项,因为我真的希望我的作者能够浏览其他作者的页面,以便找到正确的位置来添加他们的页面。
否则, 仅从新创建的文章菜单项(在步骤 1 中)将页面添加到正确位置非常麻烦。
- 按照@Igor Margitich 的建议添加这些“之前”挂钩。我也使用了 before_create_page 挂钩,因为我希望我的作者只能添加一种类型的页面。
from wagtail.core import hooks
from django.core.exceptions import PermissionDenied
from django.views.defaults import permission_denied
from .models import Article
@hooks.register('before_edit_page')
def before_edit_page(request, page):
# user_group = request.user.groups.filter(name='Author').exists() # I did not use user_group
if not (request.user.is_superuser or page.owner == request.user):
return permission_denied(request, PermissionDenied("You do not have permission to edit this page."))
@hooks.register('before_delete_page')
def before_delete_page(request, page):
if not (request.user.is_superuser or page.owner == request.user):
return permission_denied(request,PermissionDenied("You do not have permission to delete this page."))
@hooks.register('before_create_page')
def before_create_page(request, parent_page, page_class):
if not (request.user.is_superuser or page_class == Article):
return permission_denied(request, PermissionDenied("You do not have permission to add this page."))
我正在创建一个 wagtail 网站,用户可以在其中注册、登录到 wagtail 管理员并编写要发布的文章页面。 wagtail admin 中是否有拦截和过滤数据的钩子或可能的方法,以便用户只能看到他们自己创建的文章页面?
到目前为止,我已经使用 django-allauth 设置了用户注册,并且用户能够成功登录。一旦注册,user_signed_up 接收者就会触发,用户将被分配到 'Author' 角色。在管理员中,作者只能添加文章。 Articles 是一个带有文章索引页和文章页(基本上是博客和博客索引页)的应用程序。一旦他们登录,他们唯一看到的就是左侧的“页面”选项卡,单击该选项卡会将他们带到 'Articles' 列表。他们可以在这里添加 'Article' 页面并查看他们目前创建的文章。
这也是我的问题所在。在文章列表页面,用户可以看到站点上所有用户创建的所有文章。他们只能编辑自己的,这很好,但最终会有数百篇来自其他用户的文章。有没有办法在 'Articles' 数据显示之前拦截它并由当前用户过滤?
拦截此数据的结果将使登录到 wagtail 管理员的每个用户只知道他们创建的文章页面。
非常感谢,这是我第一次使用 Wagtail,到目前为止我很喜欢它。
我发现了这个问题的两种不同的解决方案。
- 实施 ModelAdmin 以创建模型的自定义页面列表视图。这使您可以创建一个全新的管理菜单项和相应的列表视图。此方法涉及更多,但提供更多控制。
- 按组对文件管理器结果实施 construct_explorer_page_queryset 管理挂钩。此方法实施起来快速且容易,并允许您使用 Wagtails 现有的页面浏览器。
我将介绍我是如何处理上述每种方法的。两者都有效,这是决定我是否更喜欢使用页面浏览器中内置的 Wagtails 的问题。
方法一:ModelAdmin
ModelAdmin.get_queryset() 的使用和其他有用的方法在 Wagtail 文档中找到 here。
根据 Wagtail 文档中的 this page,我将 ModelAdmin 添加到 INSTALLED_APPS:
# base.py settings
INSTALLED_APPS = [
...
'wagtail.contrib.modeladmin',
]
然后我在我的 'article' 应用程序中创建了一个名为 wagtail_hooks.py 的文件。在该文件中,我添加了代码以在管理员中创建我的文章列表页面:
# wagtail_hooks.py
from wagtail.contrib.modeladmin.options import (ModelAdmin, modeladmin_register)
from .models import Article
class ArticleAdmin(ModelAdmin):
model = Article
menu_label = 'Articles'
menu_icon = 'doc-full-inverse'
menu_order = 000
add_to_settings_menu = False
exclude_from_explorer = False
list_display = ('title', 'owner')
search_fields = ('title', 'owner')
def get_queryset(self, request):
qs = super().get_queryset(request)
#only show articles from the current user
return qs.filter(owner=request.user)
modeladmin_register(ArticleAdmin)
这里的关键是实现 ModelAdmin.get_queryset() 让我过滤文章所有者。
您可能还想删除页面浏览器菜单项,因为它有点多余。我还建议也实施下面的方法 2。即使您删除了页面浏览器菜单项,用户也可能通过直接在浏览器中输入 URL 来到达那里。如果他们这样做,实施方法 2 将确保看不到其他用户创作的内容。
方法二:construct_explorer_page_queryset @hooks
Wagtail 文档中的 hook 信息 - construct_explorer_page_queryset 还引用了这篇 Google 网上论坛文章 - https://groups.google.com/forum/#!topic/wagtail/10tcq8PB8io
在我上面创建的同一个 wagtail_hooks.py 文件中,我添加了以下代码:
@hooks.register('construct_explorer_page_queryset')
def show_authors_only_their_articles(parent_page, pages, request):
user_group = request.user.groups.filter(name='Author').exists()
if user_group:
pages = pages.filter(owner=request.user)
return pages
第二种方法就是这些。
@Pahikua 请注意,方法 2 只是将页面从列表中隐藏起来,并不能防止页面被编辑和删除。在您的情况下,这意味着 Author1 可以像 pages/id/edit/ 这样打开 url,其中 id 是 Author2 拥有的页面的 ID 并对其进行编辑。
要避免这种情况,您必须添加 before_edit_page 和 before_delete_page 挂钩。像这样:
@hooks.register('before_edit_page')
def before_edit_page(request, page):
user_group = request.user.groups.filter(name='Author').exists()
if user_group and page.owner != request.user:
raise PermissionDenied
感谢@Pahikua 和@Igor Margitich。我能够将他们的答案组合成一个漂亮的排列,这正是我想要的。
- 按照@Pahikua 在他的方法 1 中的建议,为文章(或您希望作者能够使用的任何其他模型)创建一个管理菜单项。这将为作者提供快速访问其内容的快捷方式(甚至可以从此处添加内容)。
- 我没有删除 Page Explorer 管理菜单项,因为我真的希望我的作者能够浏览其他作者的页面,以便找到正确的位置来添加他们的页面。
否则, 仅从新创建的文章菜单项(在步骤 1 中)将页面添加到正确位置非常麻烦。 - 按照@Igor Margitich 的建议添加这些“之前”挂钩。我也使用了 before_create_page 挂钩,因为我希望我的作者只能添加一种类型的页面。
from wagtail.core import hooks
from django.core.exceptions import PermissionDenied
from django.views.defaults import permission_denied
from .models import Article
@hooks.register('before_edit_page')
def before_edit_page(request, page):
# user_group = request.user.groups.filter(name='Author').exists() # I did not use user_group
if not (request.user.is_superuser or page.owner == request.user):
return permission_denied(request, PermissionDenied("You do not have permission to edit this page."))
@hooks.register('before_delete_page')
def before_delete_page(request, page):
if not (request.user.is_superuser or page.owner == request.user):
return permission_denied(request,PermissionDenied("You do not have permission to delete this page."))
@hooks.register('before_create_page')
def before_create_page(request, parent_page, page_class):
if not (request.user.is_superuser or page_class == Article):
return permission_denied(request, PermissionDenied("You do not have permission to add this page."))