yestema
yestema

Reputation: 8102

Simple Filter in django rest framework

I have 2 models: author and comment. I need to get list of comments filtered by author_id! Something like this:

  1. api/authors/author_id/comments
  2. or this: api/comments?author_id=author_id
  3. or this: api/comments/author/author_id

Here is official docs: http://www.django-rest-framework.org/api-guide/filtering

Here is similar question: Filtering in django rest framework

It doesn't help me. Unfortunately, there are no full simple examples for this task in internet.

Please tell me, what should I change in my code to do this filtering?

My code:

# models.py
from django.db import models
from django.utils import timezone

class Author(models.Model):
    name = models.CharField(max_length=200)

class Comment(models.Model):
    author = models.ForeignKey('Employee', related_name='author_comments')
    text = models.TextField(blank=True)
    published = models.BooleanField(default=True)
# serializer.py
from rest_framework import serializers
from core.models import Author, Comment

class AuthorSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Author
        fields = '__all__'

class CommentSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Comment
        fields = '__all__'
# views.py
from rest_framework import viewsets
from models import  Author, Comment
from serializers import AuthorSerializer, CommentSerializer

class CommentViewSet(viewsets.ModelViewSet):
    queryset = Club.objects.all()
    serializer_class = ClubSerializer
# urls.py
from django.conf.urls import url, include
from rest_framework import routers
from . import views

router = routers.DefaultRouter()
router.register(r'comments', views.CommentViewSet)

Upvotes: 0

Views: 2271

Answers (3)

Symmetric
Symmetric

Reputation: 4723

Nested URLs are unnecessarily difficult in DRF. As the issue that you linked hints, it's simplest to just extract a query parameter:

class CommentViewSet(viewsets.ModelViewSet):
    serializer_class = ClubSerializer

    def get_queryset(self):
        queryset = Club.objects.all()
        author_id = self.request.query_params.get('author_id')

        if author_id is not None:
            queryset = queryset.filter(author_id=author_id)
        return queryset

You'd use this like your option 2 above:

api/comments?author_id=author_id

Upvotes: 0

gutierri
gutierri

Reputation: 87

DRF-extensions has a feature called Nested routes that allows you to append route logic to ViewSets (which is your case). It looks like what you want and the simplest.

Upvotes: 1

Darshan
Darshan

Reputation: 457

You need to create filtered query set. here in this example i have filtered comments by author id

views.py

class CommentFilter(generics.ListAPIView):
    serializer_class = CommentSerializer

    def get_queryset(self):
        """
        This view should return a list of all the comments for
        particular author by author portion of the URL.
        """
        username = self.kwargs['author_id']
        return Comment.objects.filter(author__id=author_id)

urls.py

from django.conf.urls import url, include
from rest_framework import routers
from . import views

router = routers.DefaultRouter()
router.register(r'comments', views.CommentViewSet)
router.register(r'comment_list/(?P<author_id>\d+)/?$', views.CommentFilter,base_name="comment_list")

Hope it works.

Upvotes: 0

Related Questions