Search code examples
pythondjangodjango-rest-frameworkdjango-filter

How to filter data in DRF from database by multiple keywords?


I'm a beginner and develop a little REST API project with Django rest framework. There are a bunch of records in PostgreSQL database with a text field and I have some lists of keywords. I'm trying to filter data which contain words from one or some my lists of keywords in this text field.

Can you advise me another way around to organize filtering in DRF by using a whole list of keywords at once without entering them in a form?

I'm trying to do it with django_filters

Here if filter class:

# filter

class DataFilter(django_filters.rest_framework.FilterSet):
    keyword = CharFilter(field_name='description', lookup_expr='icontains')

    class Meta:
        model = Data
        fields = ('keyword', )

Here if view class:

# view

class DataList(generics.ListAPIView): 

    def get_queryset(self):
        return Data.objects.filter(deadline__gte=date.today())

    serializer_class = DataSerializer   
    filter_backends = (filters.DjangoFilterBackend,)
    filterset_class = DataFilter

But in this case, it filters only by one word which I enter in the form.


Solution

  • I think you can do it like this:

    First, create a new filter set subclassing from BaseInFilter and CharFilter:

    class CharInFilter(django_filters.BaseInFilter, django_filters.CharFilter):
        pass
    

    Then, update your FilterSet class like this:

    class DataFilter(django_filters.FilterSet):
        keyword__in = CharInFilter(field_name='keyword', lookup_expr='in')
    
        class Meta:
            model = Data
            fields = []
    

    Then you can use this FilterSet(same as your current implementation) like this:

    class DataList(generics.ListAPIView): 
    
        def get_queryset(self):
            return Data.objects.filter(deadline__gte=date.today())
    
        serializer_class = DataSerializer   
        filter_backends = (filters.DjangoFilterBackend,)
        filterset_class = DataFilter
    

    While using this filterset in DRF template, you need to input your values in comma separated format, like this: enter image description here