Home > other >  Django Rest Framework filtering a field with null and multiple values
Django Rest Framework filtering a field with null and multiple values

Time:03-04

I am using Django Rest Framework and want to filter the queryset in a view based on a certain field name.

The filter values would be null and additionally any other particular value for the field blog_category which is a ForeignKey value. So filter query should be on two query params

class Blog(ListCreateAPIView):
    permission_classes = [DjangoCustomModelPermissions]
    queryset = Blog.objects.all().select_related("blog_category")
    serializer_class = Blog_Serializer
    pagination_class = CustomPageNumberPagination
    filterset_fields = {'blog_category': ['isnull', 'exact', 'in']}

I have added the lookup fields isnull to filter null values

I have tried the following url requests but they do not work

/blog/?blog_catgeory__in=1,null
/blog/?blog_catgeory__in=1,isnull
/blog/?blog_catgeory__in=1,isnull=true
/blog/?blog_catgeory__in=1&blog_category__isnull=true

How do I get this work?

Edit After answer Javohir Elmurodov's answer

I made the following modifications but it still does not work

class NumberInFilter(django_filters.BaseInFilter, django_filters.NumberFilter):
    pass


class BlogFilter(filters.FilterSet):
    blog_category = NumberInFilter(field_name='blog_category', lookup_expr='in')
    blog_category__isnull = BooleanFilter(
        field_name='blog_category', lookup_expr='isnull')


class Blog_ListView(ListData, CreateData, CustomGenericAPIView):
    permission_classes = [DjangoCustomModelPermissions]
    queryset = Blog.objects.all().select_related("blog_category")
    serializer_class = Blog_Serializer
    pagination_class = CustomPageNumberPagination
    filterset_class = BlogFilter

I tried the following links

/blog/?blog_catgeory=1&blog_category__isnull
/blog/?blog_catgeory=1&blog_category__isnull=true

Still does not work

I want to search for all entries in queryset that are null OR a particular value in blog_category

CodePudding user response:

It’s not always appropriate to directly match a filter to its model field’s type, as some lookups expect different types of values. This is a commonly found issue with in, range, and isnull lookups.

While the underlying column type for category is an integer, isnull lookups expect a boolean value.

You can check in Filter and lookup expression mismatch (in, range, isnull)

CodePudding user response:

The above problem can be solved by overriding the filter method

from django.db.models import Q
from django_filters import rest_framework as filters
from django_filters import CharFilter

class BlogFilter(filters.FilterSet):
    blog_category = CharFilter(field_name='blog_category_mast',
                               lookup_expr='exact',method='include_null')

    def include_null(self, queryset, name, value):
        return queryset.filter(
            Q(**{f'{name}__isnull': True}) | Q(**{name: value})
        )


class Blog(ListCreateAPIView):
    permission_classes = [DjangoCustomModelPermissions]
    queryset = Blog.objects.all().select_related("blog_category")
    serializer_class = Blog_Serializer
    pagination_class = CustomPageNumberPagination
    filterset_class = BlogFilter

  • Related