Intro

Let’s assume that I have an endpoint like below, linked to usual generics.ListCreateAPIView:

  • /api/articles/ - GET, POST
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# articles/views.py
from rest_framework import generics

from src.articles.models import Article
from src.articles.serializer import ArticleSerializer


class ArticleListView(generics.ListCreateAPIView):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer

As you may already know you can fetch all articles via GET and post a new article via POST with required data in the body.

OK, the question is how can I filter articles against queryset parameters? Like;

Solution

The default behavior of REST framework’s generic list views is to return the entire queryset for a model manager. We should overwrite the default get_queryset method;

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# articles/views.py
from rest_framework import generics

from src.articles.models import Article
from src.articles.serializer import ArticleSerializer


class ArticleListView(generics.ListCreateAPIView):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer
    region_separator = ","

    def get_queryset(self):
        """
        Optionally restricts the returned articles to given regions,
        by filtering against a `regions` query parameter in the URL.
        """
        regions = self.request.query_params.get("regions", None)
        if regions:
            qs = Article.objects.filter()
            for region in regions.split(self.region_separator):
                qs = qs.filter(regions__code=region)

            return qs

        return super().get_queryset()

It filters articles when regions query param provided, when there is no param it returns all articles.

All done!