Фильтровать комбинированный набор запросов в Django Rest Framework
Я создал viewset, который объединяет различные модели, наследуемые от одной и той же родительской модели (транзакции). Все работало хорошо, и я смог достичь конечной точки. Сейчас я пытаюсь добавить фильтры с помощью django-filters, но получаю сообщение об ошибке:
model = queryset.model
AttributeError: 'list' object has no attribute 'model'
Поля, которые я использую для фильтрации и поиска, принадлежат родительской модели.
Вот мой набор представлений:
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
Я вижу, что ошибка заключается в том, что мой метод возвращает список вместо набора запросов, но я попытался использовать метод union вместо этого и получил
raise NotSupportedError(
django.db.utils.NotSupportedError: Calling QuerySet.filter() after union() is not supported.
Есть ли способ использовать стандартные filterset_fields и search_fields с комбинированным набором запросов?
"Умным" взломом было бы переопределение .filter_queryset(..)
:
class TransactionViewSet(viewsets.ReadOnlyModelViewSet):
serializer_class = TransactionSerializer
filter_backends = [DjangoFilterBackend, filters.SearchFilter]
filterset_fields = {
"company": ["exact"],
}
search_fields = ["id", "description"]
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
Но на самом деле объединение двух разных моделей - это обычно то, чего вам следует избегать.