如何在Django Rest Framework中正确实现日期过滤功能
DRF 日期过滤返回多结果问题修复方案
问题根源
你遇到的问题通常由以下几个原因导致:
- DRF 3.10及以上版本废弃了
filter_class属性,替换为filterset_class,旧属性配置不会生效,接口会直接返回全量数据 - 视图未配置对应过滤后端,过滤规则无法触发
date__date是匹配DateTime字段的日期部分,若数据库中同一天存在多条Fixture数据自然会返回多个结果,不符合单条返回的预期
修复代码
调整过滤类和视图配置
import django_filters from rest_framework import viewsets, permissions from .models import Fixture from .serializers import FixtureSerializer class FixtureFilter(django_filters.FilterSet): # 显式指定field_name兼容新旧版本django-filter date = django_filters.DateFilter(field_name='date__date', lookup_expr='exact') # 若需要精确匹配DateTime的时分秒,替换为下面的写法 # date = django_filters.DateTimeFilter(field_name='date', lookup_expr='exact') class Meta: model = Fixture fields = ['date'] class FixtureViewSet(viewsets.ReadOnlyModelViewSet): queryset = Fixture.objects.all().order_by('-date') serializer_class = FixtureSerializer permission_classes = [permissions.IsAuthenticated] # 替换废弃的filter_class为filterset_class filterset_class = FixtureFilter # 显式指定过滤后端,全局配置过可省略 filter_backends = [django_filters.rest_framework.DjangoFilterBackend] # 若强制要求无论匹配结果多少都只返回1条,可重写list方法 # def list(self, request, *args, **kwargs): # queryset = self.filter_queryset(self.get_queryset()).first() # return Response(self.get_serializer(queryset).data)
可选:全局配置过滤后端
在项目settings.py中添加以下配置,所有视图默认生效过滤规则,无需单独配置filter_backends:
REST_FRAMEWORK = { 'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'] }
验证
修改完成后调用接口http://localhost:8000/api/v1/fixtures?date=2021-11-29,即可按预期返回匹配结果。
内容的提问来源于stack exchange,提问作者Sander Bakker
相关产品推荐
相关产品推荐

