DjangoFilterBackend, похоже, не вызывает `filter()` на менеджере объектов
Я создаю приложение DRF/Django и пытаюсь запустить фильтрацию на одной из моих моделей. ModelViewSet, о котором идет речь, использует DjangoFilterBackend для фильтрации, и фильтрация работает правильно, но фильтрация, похоже, не вызывает функцию filter на менеджере модели.
ExModelViewset
class ExModelViewSet(ModelViewSet):
filter_backends = [
ExDjangoFilterBackend,
]
def filter_queryset(self, *args, **kwargs):
filtered_queryset = super().filter_queryset(*args, **kwargs)
print(type(filtered_queryset.model.objects))
return filtered_queryset
Это печатает <class 'assets.mixins.LinkedNodeManager'>, поэтому мы используем правильный менеджер.
EDjangoFilterBackend
class ExDjangoFilterBackend(DjangoFilterBackend):
def filter_queryset(self, request, queryset, view):
queryset = super().filter_queryset(request, queryset, view)
return queryset
DeliverableViewSet
class DeliverableViewSet(ExModelViewSet):
"""Allows REST access to the Deliverable model"""
queryset = (
models.Deliverable.objects.all()
.select_related("node", "asset", "language", "node__kind")
.prefetch_related("node__links", "asset__publications", "asset__publications__platform")
.order_by("node__path")
)
serializer_class = serializers.ExDeliverableSerializer
filter_fields = {
"node": ["exact"],
"node__code": ["exact", "in"],
"node__code_path": ["exact", "istartswith"],
"node__depth": ["lte", "exact"],
"node__kind__code": ["exact", "in"],
"node__links__code": ["exact", "in"],
"node__links__code_path": ["exact", "in", "istartswith"],
"kind__code": ["exact", "in"],
"language__code": ["exact", "in"],
}
search_fields = []
Вы видите, что здесь используется менеджер objects, который использует правильный mixin.
LinkedNodeManager & LinkedNodeManagerMixin
class LinkedNodeManager(ExManager):
"""Appends linked nodes to filtering"""
def get(self, *args, **kwargs):
print("I'm in the get!")
node__code_path = kwargs.pop("node__code_path", None)
if node__code_path is not None:
kwargs["node__code_path"] = node__code_path
return super().get(*args, **kwargs)
def filter(self, *args, **kwargs):
print("I'm in the filter!")
node__code_path = kwargs.pop("node__code_path", None)
results = super().filter(*args, **kwargs)
if node__code_path is not None:
results = results.filter(node__code_path=node__code_path)
return results
class LinkedNodeManagerMixin(Model):
objects = LinkedNodeManager()
class Meta(Model.Meta):
abstract = True
Когда я вызываю GET {{hostname}}/assets/deliverables/?language__code=eng&node__code_path=CODE_PATH, фильтрация работает как ожидалось (на основе функциональности DjangoFilterBackend), но утверждения печати не выводятся. Но, правильный класс менеджера печатается в вызове filter_queryset на наборе представлений.
Есть ли другая функция в менеджере, используемая для фильтрации DjangoFilterBackend?