问题
I am working on a small site using Wagtail. This site is all about a "mainpage" and several "subpages". So far it is pretty simple! But, depending on what group the user (not admin) is in, the right subpages should show up!
See the following setup (minimized), to get an idea of what I am talking about.
If I set permissions on ToolKitPart (like requiring explicit user-login and group-membership), then the following is happening:
when going to the page using the fully qualified path, the user is requested to login and, in the case of insufficient rights, the user will not see the content!
when going to the ToolkitIndex-Page, all children are displayed, including the ones the user never should see, without the need to be logged in or being a member of a certain group.
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'
Any idea how to solve this?
回答1:
Assuming you've set these permissions up using Wagtail's private pages feature, these are stored in the PageViewRestriction model. Unfortunately Wagtail doesn't currently provide a way to apply these permission checks against anything other than the current page request, so you'd have to recreate this logic yourself to filter a queryset to the user's view permissions. This would be something like (untested):
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())
)
Disclaimers:
- This doesn't account for pages that are protected by a shared password
- To be fully correct, we'd need to account for the fact that view restrictions propagate down the tree (and so a subpage may still be restricted even if it doesn't have a view restriction record directly attached to it); however, we're only looking at immediate children of the current page (which they evidently do have access to...) so that issue doesn't come up here.
PageViewRestriction
is not a public Wagtail API and may change in future releases - in particular, see RFC 32 for a proposed change that may happen in the fairly near future.
来源:https://stackoverflow.com/questions/54629835/wagtail-filter-page-childs-elements-on-the-basis-of-logged-in-users-permissions