python - Wagtail 根据登录用户的权限过滤页面子元素

标签 python django wagtail

我正在使用 Wagtail 开发一个小型网站。该网站由一个“主页”和几个“子页面”组成。到目前为止,一切都非常简单!但是,根据用户(不是管理员)所在的组,应该显示正确的子页面!

请参阅以下设置(最小化),以了解我在说什么。

如果我在 ToolKitPart 上设置权限(例如要求显式用户登录和组成员身份),则会发生以下情况:

  • 当使用完全限定路径访问页面时,会要求用户登录,如果权限不足,用户将看不到内容!

  • 当转到 ToolkitIndex-Page 时,会显示所有子项,包括用户永远不应该看到的子项,而无需登录或成为某个组的成员。

    class ToolkitIndex(Page):
        def get_context(self, request):
            # Update context to include only published posts, ordered by reverse-chron
            context = super().get_context(request)
            blogpages = self.get_children().live().order_by('-first_published_at')
            context['pages'] = blogpages    
            return context
    
    class ToolkitPart(Page):
        body = StreamField([
            ('staff', MpStaff()),
            ('news', MpNews()),
            ('stuff', MpStuff()),
            ('teditor', blocks.RichTextBlock()),
            ('reditor', blocks.RawHTMLBlock()),
        ], blank=True)
    
        content_panels = Page.content_panels + [
            StreamFieldPanel('body'),
        ]
    
    class MpNews(blocks.StructBlock):
        head = blocks.TextBlock(required=True, help_text='Schlagzeile')
        lead = blocks.TextBlock(required=False, help_text='Einleitung')
        body = blocks.RichTextBlock(required=True, help_text='Inhalt')
        image = ImageChooserBlock(required=False)
    
        type = blocks.ChoiceBlock(
            choices=[('default', 'Standard'),
                 ('highlight', 'Hervorgehoben'),
                 ], required=True)
    
        class Meta:
            template = 'home/mparts/toolkit_news.html'
            icon = 'code'
    

知道如何解决这个问题吗?

最佳答案

假设您已使用 Wagtail 的 private pages 设置了这些权限功能,这些存储在PageViewRestriction中模型。不幸的是,Wagtail 目前不提供对当前页面请求以外的任何内容应用这些权限检查的方法,因此您必须自己重新创建此逻辑,以将查询集过滤到用户的查看权限。这将类似于(未经测试):

from django.db.models import Q

class ToolkitIndex(Page):
    def get_context(self, request):
        context = super().get_context(request)
        blogpages = self.get_children().live().order_by('-first_published_at')

        if not request.user.is_authenticated:
            blogpages = blogpages.public()  # only pages with no view restrictions at all

        else:
            blogpages = blogpages.filter(
                # pages with no view restrictions
                Q(view_restrictions__isnull=True)
                # pages restricted to any logged-in user
                | Q(view_restrictions__restriction_type='login')
                # pages restricted by group
                | Q(view_restrictions__restriction_type='groups', view_restrictions__groups__in=request.user.groups.all())
            )

免责声明:

  • 这不考虑受共享密码保护的页面
  • 为了完全正确,我们需要考虑 View 限制沿着树传播的事实(因此,即使子页面没有直接附加 View 限制记录,它仍然可能受到限制);但是,我们只查看当前页面的直接子页面(它们显然确实可以访问...),因此这里不会出现这个问题。
  • PageViewRestriction 不是公共(public) Wagtail API,可能会在未来版本中发生更改 - 特别是,请参阅 RFC 32以便在不久的将来可能发生拟议的更改。

关于python - Wagtail 根据登录用户的权限过滤页面子元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54629835/

相关文章:

python - 如何从多维缓冲区初始化 NumPy 数组?

python pubsub 订阅多个主题

c++ - 带子类的django循环

python - 属性错误: type object 'Team' has no attribute '_meta'

python - 找不到参数 'wagtailadmin_explore' ',)' 的 '(' 反向

python - 在 python、bash 或 perl 中,如何人为地增加内存

django - 用户历史记录操作 - 在 django 模型中存储的正确方法

django - Python-ModuleNotFoundError : No module named 'django.db.migrations.migration'

python - Wagtail 自定义内联 PageChooser

python - Python 中的相同对象问题