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]