using django-rest-framework how query works for list fields?

486 views Asked by At

I'm using get_queryset with Django-REST-Framework to build APIs for my app.

I would like to know if there's a way to get this filter working

http://api/data?district=Nasik,Pune

to get all data with district "Pune" OR district "Nasik". I've tried with

http://api/data?district=Nasik&district=Pune but as expected it does an AND between the filters and retrieve only the Pune district (i suppose because it's the last filter).

Here is my code :

from rest_framework_mongoengine.viewsets import ModelViewSet as MongoModelViewSet
from app.serializers import *
from mongoengine.queryset.visitor import Q

class ToolViewSet(MongoModelViewSet):

    serializer_class = ToolSerializer

    def get_queryset(self, *args, **kwargs):
        queryset_list =Tool.objects.all()
        fruit=self.request.query_params.get("fruit")
        district=self.request.query_params.get("district")
        taluka=self.request.query_params.get("taluka")

        if fruit and district:
            queryset_list = queryset_list.filter(
            Q(fruit__icontains=fruit)
            &Q(district__icontains=district)
            )
            return queryset_list

        if fruit and taluka:
            queryset_list = queryset_list.filter(
            Q(fruit__icontains=fruit)
            &Q(taluka__icontains=taluka)
            )
            return queryset_list


        if district and taluka:
            queryset_list = queryset_list.filter(
            Q(district__icontains=district)
            &Q(taluka__icontains=taluka)
            )
            return queryset_list

        elif fruit:
            queryset_list = queryset_list.filter(
            Q(fruit__icontains=fruit)
            )
            return queryset_list

        elif district:
            queryset_list = queryset_list.filter(
            Q(district__icontains=district)
            )  
            return queryset_list

        elif taluka:
            queryset_list = queryset_list.filter(
            Q(taluka__icontains=taluka)
            )  
            return queryset_list

so, this code working for two different fields,

for example:

http://api/?data?fruit=Banana&district=Pune

http://api/?data?fruit=Banana&taluka=Haveli

http://api/?data?taluka=Haveli&district=Pune

all are working but,

http://api/data?district=Nasik,Pune

this is not working, here I use this code for "OR"

if district or district:
    queryset_list = queryset_list.filter(
        Q(district__icontains=fruit)
        |Q(district__icontains=district)
    )
    return queryset_list

but it's not working, any idea how to solve this ?

1

There are 1 answers

2
AudioBubble On

You have to define the new filter for this. As reference to django-filter issue https://github.com/carltongibson/django-filter/issues/137

from django_filters import Filter
from django_filters.fields import Lookup

class ListFilter( Filter ):
  def filter( self, qs, value ):
    return super( ListFilter, self ).filter( qs, Lookup( value.split( u"," ), "in") )

Have you got both the value Pune & Nashik in get_queryset method ?

Note: - Updated

Cloud you please try this code in order to get both the district value.

fields = request.query_params.get('district ')
    if fields:
        fields = fields.split(',')
        dis = set(fields)  # dis is a set of all request param value.