I've recently upgraded to 2.0, which apart from this particular issue, went quite well. I am using query-set annotations as quick read-only fields. I define supported look-ups for these fields in Meta.fields
, but as of 2.0, these now work only for actual model fields:
class MySerializer(ModelSerializer):
annotated_field = IntegerField(read_only=True)
class Meta:
model = MyModel
fields = ('model_field', 'annotated_field')
class MyFilterSet(FilterSet):
annotated_field = NumberFilter()
class Meta:
model = MyModel
fields = {'model_field': ['exact', 'gt', 'lt'], # <-- Works as expected.
'annotated_field': ['exact', 'gt', 'lt']} # <-- Doesn't work for me.
class MyViewSet(ModelViewSet):
serializer_class = MySerializer
filterset_class = MyFilterSet
filter_backends = (DjangoFilterBackend,)
queryset = MyModel.objects.annotate(
annotated_field=Coalesce('field_a', 'field_b', 'field_c'))
As you can see above, my Meta.fields
defines exact, gt and lt as look-ups available to both the model and the annotated field. For some reason, I can't get the annotated field look-ups to work and I am sure this was OK in 1.x. Has this functionality been deprecated or accidentally removed?
Thank you in advance.
Hi @markgajdosik. I don't believe this functionality ever existed. Meta.fields
works by inspecting a model's fields during FilterSet
class creation. Annotations only exist on a queryset, which is provided during per-instance initialization.
Do you know what version may have worked previously? Can you print out the following:
MyFilterSet.declared_filters
MyFilterSet.base_filters
Hey @rpkilby, thanks for getting back to me. I have to admit I didn't look into it properly until recently (separated the functionality into a blank test project with django-filter 1.x installed) and I can confirm this (probably) never worked.
Not sure what I was thinking. I'll be using a more verbose, but functional way of achieving this:
class MyFilterSet(FilterSet):
field = NumberFilter()
field__gt = NumberFilter(field_name='field', lookup_expr='gt')
field__lt = NumberFilter(field_name='field', lookup_expr='lt')
...
Most helpful comment
Hey @rpkilby, thanks for getting back to me. I have to admit I didn't look into it properly until recently (separated the functionality into a blank test project with django-filter 1.x installed) and I can confirm this (probably) never worked.
Not sure what I was thinking. I'll be using a more verbose, but functional way of achieving this: