Sizzling Code
Sizzling Code

Reputation: 6070

Filter the queryset in Python 3 and jQuery DataTables

I am trying to query on jQuery Datatables list.

Right now I can fetch all records from the table, but I want to fetch records to whom their parent id matches.

For example, users have posts, so in my case it would be fetch posts where user id is lets say 1.

So I am trying to implement same thing for jQuery Datatables.

I can see data is being posted but I can't figure out how to query along with datatables, so that datatables filters are not affected by this change.

My current code:

class PartRequestViewSet(CommonViewset, generics.RetrieveAPIView):
    queryset = PartRequest.objects.filter(deleted_at=None)
    serializer_class = PartRequestSerializer

    def list(self, request, *args, **kwargs):
        records = request.GET.get('records', None)
        # ID of the part
        part_number_id = request.GET.get('part_number_id', None)

        queryset = self.get_queryset()
        queryset = self.filter_queryset(queryset)
        page = self.paginate_queryset(queryset)
        if page is not None and records is None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = self.get_serializer(queryset, many=True)

        return Response(serializer.data)


Now in above code I can get the part_number_id from request, but how can I filter records using filter_queryset(), so that only parts_requests are given back in datatables where part_number_id is 1

Update

Current helper function filter_queryset that is used in above code.

    def filter_queryset(self, queryset):
        format = self.request.GET.get('format', None)
        if format == 'datatables':
            self.filter_backends += (DatatablesFilterBackend,)
        else:
            self.filter_backends += (DjangoFilterBackend,)
        for backend in list(self.filter_backends):
            queryset = backend().filter_queryset(self.request, queryset, self)
        return queryset

Upvotes: 0

Views: 591

Answers (2)

Sizzling Code
Sizzling Code

Reputation: 6070

The way I did is I added the following lines:

 if part_number_id:
     queryset = queryset.filter(part_number_id=part_number_id)

so the code looks like this now and it is working great. I'm open to better and more efficient options.

class PartRequestViewSet(CommonViewset, generics.RetrieveAPIView):
    queryset = PartRequest.objects.filter(deleted_at=None)
    serializer_class = PartRequestSerializer

    def list(self, request, *args, **kwargs):
        records = request.GET.get('records', None)
        # ID of the part
        part_number_id = request.GET.get('part_number_id', None)
        queryset = self.get_queryset()
        queryset = self.filter_queryset(queryset)
        if part_number_id:
            queryset = queryset.filter(part_number_id=part_number_id)
        page = self.paginate_queryset(queryset)
        if page is not None and records is None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = self.get_serializer(queryset, many=True)

        return Response(serializer.data)

Upvotes: 0

Glech
Glech

Reputation: 781

There is django-filter extension. In your case it may be something like the following:

from rest_framework import viewsets
from django_filters.rest_framework import DjangoFilterBackend

from .models import Post
from .serializers import PostSerializer


class PostList(viewsets.ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['owner']

Then you can use get request like this: /posts?owner=3, where 3 is user id and owner is ForeignKey in Post model to User.

Upvotes: 1

Related Questions