Skip to content

Instantly share code, notes, and snippets.

@cnk
Created September 17, 2020 18:08
Show Gist options
  • Save cnk/ff82eb910e42a26b108395a149ea7025 to your computer and use it in GitHub Desktop.
Save cnk/ff82eb910e42a26b108395a149ea7025 to your computer and use it in GitHub Desktop.
#################################################################################################################
# Patch the wagtail.admin.forms.pages.PageViewRestrictionForm class to filter groups to only those available
# to the current site.
#################################################################################################################
def page_view_restriction_init(self, *args, **kwargs):
super(PageViewRestrictionForm, self).__init__(*args, **kwargs)
self.fields['groups'].widget = forms.CheckboxSelectMultiple()
# BEGIN PATCH
current_site = Site.find_for_request(get_current_request())
self.fields['groups'].queryset = Group.objects.filter(name__istartswith=current_site.hostname)
# END PATCH
# and now use this method instead of the usual init
wagtail.admin.forms.pages.PageViewRestrictionForm.__init__ = page_view_restriction_init
@cnk
Copy link
Author

cnk commented Sep 18, 2020

How to get that patch file to take effect:

We have a number of patches so we have an entire django app called wagtail_patches which is included in our INSTALLED_APPS after our other apps but before we load the wagtail apps such as 'wagtail.core', etc.

I don't see anything special in our wagtail_patches/apps.py file that would explicitly load monkey_patches.py but that doesnt mean there isn't some magic I am not seeing.

@cnk
Copy link
Author

cnk commented Sep 21, 2020

Further questions showed up that get_current_request is from a custom middleware we have installed - that is a light wrapper around CrquestMiddleware

#python

from crequest.middleware import CrequestMiddleware

def get_current_request(default=None, silent=True, label='__DEFAULT_LABEL__'):
    """
    Returns the current request. This is a more robust form of get_current_request, but it's not backwards compatible,
    so we gave it a different name.

    You can optionally use ``default`` to pass in a dummy request object to act as the default if there is no current
    request, e.g. when ``get_current_request()`` is called during a manage.py command.
    """
    request = CrequestMiddleware.get_request(default)
    if request is None and not silent:
        raise NoCurrentRequestException(
            "{} failed because there is no current request. Try using djunk.utils.FakeCurrentRequest.".format(label)
        )
    return request

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment