Django-filter больше результатов при явном задании значения фильтра

Я пытаюсь понять, что происходит, если поле, указанное в filterset_fields набора представлений, не указано. Мой набор представлений выглядит следующим образом:

class DetectionTrainingViewSet(
        mixins.ListModelMixin,
        mixins.RetrieveModelMixin,
        viewsets.GenericViewSet
    ):
    queryset = Detection.objects.all()
    serializer_class = DetectionSerializer
    filterset_fields = (
        'annotation_set__annotator__id',
        'annotation_set__bbox__annotator__id',
    )

Я делаю следующие GET вызовы моей конечной точки http://127.0.0.1:8000/api/v1/detections/:

  • ?annotation_set__annotator__id=2 -> Я получаю 4 результата
  • ?annotation_set__annotator__id=2&annotation_set__bbox__annotator__id=2 -> Я получаю 16 результатов Я ожидал, что второй вызов вернет подмножество следующего вызова. Что здесь происходит? Как я могу указать, что когда параметр не указан явно, любое значение (если оно не существует) должно соответствовать запросу?

Добавляю здесь, так как это слишком длинно для комментария:

Этого не должно происходить, поля должны быть and выведены, и по моему опыту так и есть. Я не вижу причин, почему это не будет работать из приведенного вами кода.

  1. Сколько всего записей имеется
  2. Можете ли вы увидеть на стороне сервера точный полученный запрос?
  3. Как именно вы посылаете этот запрос? cli? браузер?

Единственное, что я могу предположить, это то, что строка запроса искажается (возможно, путем urlencoding) перед отправкой.

Вот несколько простых print() отладок, которые можно добавить в набор представлений для проверки в различных точках и без подключения отладчика.

# add this to print the actual query text before & after filtering
def filter_queryset(self, queryset):
     print("[before]", queryset.query)
     queryset = super().filter_queryset(queryset)
     print("[after ]", queryset.query)
     return queryset

# add this override to see what your path / qs / etc are
def list(self, request, *args, **kwargs):
    print(request.path)
    print(request.META["QUERY_STRING"])
    print(request.query_params)
    return super().list(request, *args, **kwargs)
Вернуться на верх