Carlos
Carlos

Reputation: 935

Django Rest Framework filter class method with two parameters

I have a model which relates to many models, like this:

class Father:
   son = # Foreign key to Son model

class Son:
   @property
   def son_daughters:
      if ... :
         obj = TypeA.objects.get(...)
      elif ... :
         obj = TypeB.objects.get(...)
      else:
         obj = TypeC.objects.get(...)

      return obj

I would like to get Father data from daughter name or type. I have this filter class where I need to send two query set parameters related to daughter in order to get daughter ids and apply it as a filter to Father. This is my filter class:

class FatherFilter(django_filters.rest_framework.FilterSet):
   def daughter(self, method_name, args, **kwargs):

        print(method_name, args, kwargs)
        ...

   daughter_id = django_filters.NumberFilter(method=daughter)

But when I call this endpoint I just get one query parameter and not all.

Is there a way to get the query parameters inside this method instead of just one?

Thanks in advance.

Upvotes: 2

Views: 3934

Answers (1)

Carlos
Carlos

Reputation: 935

In order to achieve this, I found that Django Rest Framework has a class that extends from django_filters. This class is called BaseFilterBackend and can be used to extend the default backend for filtering any request. So what I did was adding a class extended from BaseFilterBackend like this:

from rest_framework import filters

class FatherFilterBackend(filters.BaseFilterBackend):
   def filter_queryset(self, request, queryset, view):
      daughter_id = request.query_params.get("daughter_id", None)
      daughter_name = request.query_params.get("daughter_name", None)

      if daughter_id and daughter_name:
         kwargs = {
            daughter_name: daughter_id
         }
         queryset = queryset.filter(**kwargs)

      return queryset

This filter will apply before others, so even if you are using a FilterSet class, you will not lose the filters from your BaseFilterBackend. The problem with this solution is that relies in rest_framework.filters package, a filter that its not related to django_filters.

This might not be the best way to achieve this, so if you have better ideas please add them to help others with a similar problem.

Upvotes: 2

Related Questions