django-filter filter on annotated field

Viewed 1838
class EventViewSet(viewsets.ModelViewSet):
    queryset = Event.objects.all()
    serializer_class = EventSerializer

    def get_queryset(self):
        return super().get_queryset().annotate(
            is_active=ExpressionWrapper(
                Q(start_date__lt=timezone.now()) & Q(end_date__gt=timezone.now()),
                output_field=BooleanField()
            ),
        )

    search_fields = [
        'name',
        'short_desc',
        'desc',
    ]

    filterset_fields = [
        'is_active',
    ]

I have this ViewSet that I want to filter on an annotated field, normally you can simply just filter on the annotation in django querysets, however the above combined with this serializer:

class EventSerializer(serializers.ModelSerializer):
    is_active = serializers.SerializerMethodField()

    @staticmethod
    def get_is_active(obj):
        return obj.is_active

    class Meta:
        model = Event
        fields = [
            'timestamp',
            'id',
            'name',
            'short_desc',
            'desc',
            'start_date',
            'end_date',
            'is_active',
        ]

I haven't looked deep into the source code but I'd assume it would do a simple qs.filter for the fields in filterset_fields but I'm getting this beautiful error that fails to explain much(at least to me):

'Meta.fields' contains fields that are not defined on this FilterSet: is_active

1 Answers

Apparently you simply don't add the declared filters on the Meta.fields list. Literally inside the docs and I found out about it by reading the code.

Also, when adding an annotated field to the declared_fields AKA the filterset class body, add a label or django-filters can't produce field label properly and just goes with "invalid name" instead of you know, the field name. Who knows why.

Related