[Answered ]-Filter api output by value stored in Join Table

1πŸ‘

βœ…

The DRF List view is executed in the following order (essential steps related to OP),

  1. request hits the view
  2. calling get_queryset() method (This internally calls queryset attribute)
  3. filtering the results using a list of filter_backends classes
  4. serializing the data
  5. returning to user/client

So, in your case, the filter_fields is being used at the 3rd step and that will not use again anywhere.


Solution

Use SerializerMethodField(...) and manually filter the related queryset as

class OriginCountrySerializer(serializers.ModelSerializer):
    origin_country = serializers.StringRelatedField(read_only=True)
    destinations = serializers.StringRelatedField(many=True, read_only=True)
    dest_country = serializers.SerializerMethodField()

    def get_dest_country(self, instance):
        qs = instance.borderstatus_set.all()
        request = self.context["request"]
        value = request.query_params.get("my_country_param")
        if value:
            qs = instance.borderstatus_set.filter(status=value)
        return BorderStatusSerializer(qs, many=True).data

    class Meta:
        model = OriginCountry
        fields = ('origin_country', 'destinations', 'dest_country')

and thus, you need to call the URL as

/?name=Germany&my_country_param=CLOSED
πŸ‘€JPG

0πŸ‘

You can use filter() instead of obejcts.all()


class CountryViewSet(viewsets.ModelViewSet):
    queryset = Country.objects.filter(status='CLOSED')

you add other conditions also


class CountryViewSet(viewsets.ModelViewSet):
    queryset = Country.objects.filter(status='CLOSED',country='Germany')

πŸ‘€Mohammad

0πŸ‘

I think you need to update the name of your filter to:

filter_fields=('origin_country','borderstatus_set__status',)
πŸ‘€Alex Carlos

Leave a comment