Reputation: 163
I'm going through the documentation at: http://docs.wagtail.io/en/v2.7.1/reference/pages/queryset_reference.html.
Is there a filter to return only the pages the user has access to? I can only see public()
and not_public()
.
I have some pages which privacy is set to Private (accessible to users in specific groups). And would like to exclude them from the query results.
Upvotes: 1
Views: 1115
Reputation: 2171
There is no such filter in PageQuerySet. You can however create your own QuerySet that adds an authorized filter and use that. The following code comes from the Joyous events EventQuerySet
and is based upon PageQuerySet.public_q
and BaseViewRestriction.accept_request
. It gets all the restrictions that could apply, excludes the ones that the user passes, and then filters out the pages with the remaining restrictions.
from wagtail.core.query import PageQuerySet
from wagtail.core.models import Page, PageManager, PageViewRestriction
class MyQuerySet(PageQuerySet):
def authorized_q(self, request):
PASSWORD = PageViewRestriction.PASSWORD
LOGIN = PageViewRestriction.LOGIN
GROUPS = PageViewRestriction.GROUPS
KEY = PageViewRestriction.passed_view_restrictions_session_key
restrictions = PageViewRestriction.objects.all()
passed = request.session.get(KEY, [])
if passed:
restrictions = restrictions.exclude(id__in=passed,
restriction_type=PASSWORD)
if request.user.is_authenticated:
restrictions = restrictions.exclude(restriction_type=LOGIN)
if request.user.is_superuser:
restrictions = restrictions.exclude(restriction_type=GROUPS)
else:
membership = request.user.groups.all()
if membership:
restrictions = restrictions.exclude(groups__in=membership,
restriction_type=GROUPS)
q = models.Q()
for restriction in restrictions:
q &= ~self.descendant_of_q(restriction.page, inclusive=True)
return q
def authorized(self, request):
self.request = request
if request is None:
return self
else:
return self.filter(self.authorized_q(request))
You could then set this to be your model's default QuerySet.
class MyPage(Page):
objects = PageManager.from_queryset(MyQuerySet)()
Then when filtering your MyPage objects you can say MyPage.objects.live().authorized(request).all()
Hope that is helpful. May contain bugs.
Upvotes: 2