TIL: Using django-filter Filtersets in Wagtail API v2

, Jochen

For this blog I have a "Filter / Full text search" box at the top. Now I wanted to build a Vue.js theme for the Wagtail based blog engine. Since I now have to fetch all posts via the Wagtail API v2, I wondered if it would be possible to keep the filter box and just pass the form data as query parameters to the API (which is based on Django REST framework).

When I tried to add one of the query parameters, I got the following error message from DRF:

Query parameter is not an operation or a recognized field: date_facets

Fortunately, it was relatively easy to combine my existing django-filter filterset called PostFilterset with a slightly modified PagesAPIViewSet by adding a use_post_filter flag:

...
class FilteredPagesAPIViewSet(PagesAPIViewSet):
    def get_filtered_queryset(self) -> QuerySet:
        # allow additional query parameters from PostFilterset + use_post_filter flag
        additional_query_params = PostFilterset.Meta.fields + ["use_post_filter"]
        self.known_query_parameters = self.known_query_parameters.union(additional_query_params)
        queryset = super().get_queryset()
        return PostFilterset(
            data=self.request.GET.copy(), queryset=queryset, fetch_facet_counts=True).qs

    def get_queryset(self):
        if self.request.GET.dict().get("use_post_filter", "false") == "true":
            return self.get_filtered_queryset()
        return super().get_queryset()

...
wagtail_api_router = WagtailAPIRouter("cast:api:wagtail")
wagtail_api_router.register_endpoint("pages", FilteredPagesAPIViewSet)

Return to blog