django-filter + DRF ModelViewSet不同字段的不同行为



我有以下ViewSets(我的当前代码)

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 = []

如果我把它改成这个(我假设它应该像TeacherSet

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

我面临的问题是

  • /school/?udise=111不工作,不过滤任何东西
  • /teacher/?user_id=4a031bd9-4c02-4f9a-8c1b-56fb68965021工作完全正常

我想我在这里错过了一些非常基本的东西。user_idudise在数据库中都是唯一的。因此,为了缓解这个问题,我目前在DRF的默认SearchFilter后端使用search_fields=

/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]