Django-filter + DRF ModelViewSet разное поведение для разных полей

У меня есть следующие наборы представлений

class TeacherViewSet(viewsets.ModelViewSet):
    queryset = Teacher.objects.all()
    serializer_class = TeacherSerializer
    filter_backends = [DjangoFilterBackend, SearchFilter]
    filterset_fields = ['user_id', ]
    search_fields = ['=user_id']


class SchoolViewSet(viewsets.ModelViewSet):
    queryset = School.objects.filter()
    serializer_class = SchoolSerializer
    filter_backends = [filters.SearchFilter]
    filterset_fields = ['udise', ]
    search_fields = ['=udise']

Модели выглядят следующим образом

class Teacher(BaseModel):
    school = models.ForeignKey(School, on_delete=models.SET_NULL, null=True)
    user_id = models.UUIDField()


class School(models.Model):
    id = models.AutoField(primary_key=True)
    udise = models.IntegerField(unique=True)

А сериализатор для School выглядит следующим образом

class SchoolSerializer(serializers.ModelSerializer):

    class Meta:
        model = School
        fields = '__all__'
        validators = []

Проблема, с которой я столкнулся, заключается в следующем

  • /school/?udise=111 doesn't work and doesn't filter anything
  • /teacher/?user_id=4a031bd9-4c02-4f9a-8c1b-56fb68965021 works perfectly fine.

I think I am missing something really basic here. Both user_id and udise are unique in the database. So to mitigate this I am currently using a hack - search_fields with and = on DRF's default SearchFilter backend.

В /school/?udise=111 и /teacher/?user_id=4a031bd9-4c02-4f9a-8c1b-56fb68965021 вы пытаетесь фильтровать, а не искать.

Поисковый url будет выглядеть примерно так: /?search=sth. Затем он ищет в указанных полях в search_fields, и пытается найти объект, соответствующий этим полям. Причем эти поля должны быть текстового типа для возможности поиска. См. документацию о поиске: https://www.django-rest-framework.org/api-guide/filtering/#searchfilter

Но здесь вы пытаетесь фильтровать, поэтому вы должны использовать DjangoFilterBackend или пользовательский фильтр для фильтрации:

class SchoolViewSet(viewsets.ModelViewSet):
    ...
    filter_backends = [DjangoFilterBackend]
Вернуться на верх