Overview

Let’s customize the views for the model added in the following article.

Sort

Let’s add ordering_fields.

...
class UserInfoViewset(ModelViewSet):
    ordering_fields = ("user_name", ) # Added here

    queryset = UserInfo.objects.all()
    serializer_class = UserInfoSerializer

    def get_object(self):
        entry_pk = self.kwargs.get("entry_pk", None)
        if entry_pk is not None:
            return Entry.objects.get(id=entry_pk).blog

        return super().get_object()

...

As a result, only user_name became selectable in the “Filters” display.

For example, sorting by age returned a validation error.

Filter

...
class UserInfoViewset(ModelViewSet):
    queryset = UserInfo.objects.all()
    serializer_class = UserInfoSerializer

    ordering_fields = ("user_name", )

    # Added from here below

    # override the default filter backends in order to test QueryParameterValidationFilter
    # without breaking older usage of non-standard query params like `page_size`.
    filter_backends = (
        QueryParameterValidationFilter,
        OrderingFilter,
        DjangoFilterBackend,
        SearchFilter,
    )

    rels = (
        "exact",
        "iexact",
        "contains",
        "icontains",
        "gt",
        "gte",
        "lt",
        "lte",
        "in",
        "regex",
        "isnull",
    )
    filterset_fields = {
        "id": ("exact", "in"),
        "user_name": rels
    }
    search_fields = ("user_name", )
    ...
...

With the above, the following filter became possible.

http://localhost:8000/user-info?filter[user_name.contains]=nakamura

For id, since only exact and in are allowed, the following resulted in a validation error.

http://localhost:8000/user-info?filter[id.contains]=2

Checking the swagger-ui confirmed that filter was correctly configured.

http://localhost:8000/swagger-ui/

ReadOnlyModelViewSet

This appears to be a Django REST framework feature, but by using ReadOnlyModelViewSet, I was able to create a view-only view.

...
class UserInfoViewset(ReadOnlyModelViewSet): # Changed here
    queryset = UserInfo.objects.all()
    serializer_class = UserInfoSerializer

    ordering_fields = ("user_name", )
...

Checking the swagger-ui confirmed that only get was set.

Summary

There are many points where my understanding is still insufficient, but I hope this serves as a useful reference for implementing filters.