DRF serializer filtering

Viewed 1740

I have a serializer that gives me everything fine.

ModelClassASerializer((serializers.ModelSerializer)):
   .....

   status = serializers.SerializerMethodField()


   def get_status(self, obj):
       ....
       status = ModelB.objects.get(id=obj.id).status
       ....
       return status

   class Meta:
       model = ModelClassA
       fields = (...)

But if I want to make a filtering based on that status, I can't. I am using django_filters.rest_framework.FilterSet for the filtering. There is no relation between models.

What is the best way to do that filtering?

1 Answers

It looks like objects in ModelA share the same IDs as those in ModelB. If that's the case, you can use a subquery to match on IDs. If the IDs do not correspond with each other, then this query will be nonsensical. You want to create the following queryset:

from django.db.models import Subquery
from myapp.models import ModelA, ModelB

pks = ModelB.objects.filter(status='foo').values('pk')
ModelA.objects.filter(pk__in=Subquery(pks))

To create the above will django-filter, you'll need to use the method argument on a filter.

from django_filters import rest_framework as filters

class ModelAFilter(filters.FilterSet):
    status = filters.ChoiceFilter(choices=(('foo', 'Foo'), ...), method='filter_status')

    class Meta:
        model = ModelA
        fields = []

    def filter_status(self, queryset, name, value):
        pks = ModelB.objects.filter(status=value).values('pk')
        return queryset.filter(pk__in=Subquery(pks))
Related