I created a viewset that combines different models that inherit from the same parent model (Transactions). It was working well and I could reach the endpoint. Now I am trying to add filters using django-filters, but I am getting an error:
model = queryset.model
AttributeError: 'list' object has no attribute 'model'
The fields that I am using to filter and search belong to the parent model.
Here is my viewset:
class TransactionViewSet(viewsets.ReadOnlyModelViewSet):
serializer_class = TransactionSerializer
filter_backends = [DjangoFilterBackend, filters.SearchFilter]
filterset_fields = {
"company": ["exact"],
}
search_fields = ["id", "description"]
def get_queryset(self):
payment_collections = PaymentCollection.objects.all()
up_front_sales = UpFrontSale.objects.all()
combined_queryset = list(
chain(
payment_collections,
up_front_sales,
)
)
return combined_queryset
I see that the error is that my method returns a list instead of a queryset, but I tried to use the union method instead and got
raise NotSupportedError(
django.db.utils.NotSupportedError: Calling QuerySet.filter() after union() is not supported.
Is there a way to use the default filterset_fields and search_fields with a combined queryset?
A "smart" hack would be to override the .filter_queryset(…)
[drf-doc]:
class TransactionViewSet(viewsets.ReadOnlyModelViewSet):
serializer_class = TransactionSerializer
filter_backends = [DjangoFilterBackend, filters.SearchFilter]
filterset_fields = {
'company': ['exact'],
}
search_fields = ['id', 'description']
queryset = PaymentCollection.objects.none()
def filter_queryset(self, queryset):
payment_collections = super().filter_queryset(
PaymentCollection.objects.all()
)
up_front_sales = super().filter_queryset(UpFrontSale.objects.all())
combined_queryset = list(
chain(
payment_collections,
up_front_sales,
)
)
return combined_queryset
But actually the union of two different models is usually something you should try to avoid.