django-viewsdjango-rest-frameworkmongoenginedjango-filterrestframeworkmongoengine

how to use django rest filtering with mongoengine for list filtering


views.py

from __future__ import unicode_literals

from rest_framework_mongoengine.viewsets import ModelViewSet as MongoModelViewSet

from app.serializers import *

from rest_framework_mongoengine.generics import * 

from rest_framework import filters    


def index_view(request):
    context = {}
    return TemplateResponse(request, 'index.html', context)


class ToolViewSet(MongoModelViewSet):
    serializer_class = ToolSerializer
    my_filter_fields = ('crop', 'district','taluka','circle','year',) 

    def get_kwargs_for_filtering(self):
        filtering_kwargs = {} 

        for field in  self.my_filter_fields: # iterate over the filter fields
            field_value = self.request.query_params.get(field) # get the value of a field from request query parameter
            if field_value: 
                filtering_kwargs[field] = field_value
        return filtering_kwargs 

    def get_queryset(self):
        queryset = Tool.objects.all() 
        filtering_kwargs = self.get_kwargs_for_filtering() # get the fields with values for filtering 
        if filtering_kwargs:
            queryset = Tool.objects.filter(**filtering_kwargs) # filter the queryset based on 'filtering_kwargs'
        return queryset

This is my code.

it's work for filtering exactly what we want to serach.

for example : http://api/tool/?district=Nasik&crop=banana

But, it's not working for list fileds for example : http://api/tool/?district=Nasik&district=Pune this gives output: [] (empty)

How to get this filter working to get all district "Nasik" OR district "Pune"

Can you please help me what I have to changes in my code for get data if I search http://api/tool/?crops=guava,banana Or http:../tool/?district=Nasik,Pune
gives me correct output?


Solution

  • I recommend taking a look at django-rest-framework-filters. You can then use stuff like __in in your query params...

    But if you want to proceed with your approach, I would add the logic in your get_kwargs_for_filtering method somehow like this:

    def get_kwargs_for_filtering(self):
        filtering_kwargs = {} 
    
        for field in  self.my_filter_fields: # iterate over the filter fields
            field_value = self.request.query_params.get(field) # get the value of a field from request query parameter
            if field_value: 
                if ',' in field_value: # put your queryParams into an array and use the built-in django filter method '__in'
                    filtering_kwargs[field + '__in'] = field_value.split(',')
                else:
                    filtering_kwargs[field] = field_value
        return filtering_kwargs
    

    With this, a call to http://api/tool/?crops=guava,banana should produce the desired behavior. I can't test if it works now, but this should lead you to the right direction.