基于时间查询用户:Django DRF类视图按创建日期区间筛选报错求助
问题修复与其他筛选方案
报错根因
你遇到的get() missing 1 required positional argument: 'to_date'报错由两个问题导致:
- DRF的APIView类视图中,HTTP方法对应的处理函数第一个固定参数是
request,你没有声明该参数,同时from_date、to_date两个参数没有配置对应的取值逻辑,DRF无法自动传入参数 - 你定义的序列化器没有被实际调用,参数没有做合法性校验就直接传入ORM查询,存在非法参数报错风险
修复方案
方案1:URL路径参数传参
views.py修改如下:
class RegisteredUserFilter(APIView): serializer_class = RegisteredUserFilterSerializer def get(self, request, from_date, to_date): # 校验日期参数合法性 serializer = self.serializer_class(data={"from_date": from_date, "to_date": to_date}) serializer.is_valid(raise_exception=True) validated_data = serializer.validated_data userondate = User.objects.filter(created_at__range=[validated_data['from_date'], validated_data['to_date']]).values() return Response({"User": userondate})
urls.py添加对应路径参数配置:
path('users/filter/<date:from_date>/<date:to_date>/', RegisteredUserFilter.as_view(), name='user-filter')
调用示例:请求/users/filter/2024-01-01/2024-02-01/即可获取对应日期区间的用户
方案2:查询参数传参(更符合筛选类接口设计规范)
views.py修改如下:
class RegisteredUserFilter(APIView): serializer_class = RegisteredUserFilterSerializer def get(self, request): # 从GET请求的查询参数中提取并校验参数 serializer = self.serializer_class(data=request.query_params) serializer.is_valid(raise_exception=True) validated_data = serializer.validated_data userondate = User.objects.filter(created_at__range=[validated_data['from_date'], validated_data['to_date']]).values() return Response({"User": userondate})
urls.py配置如下:
path('users/filter/', RegisteredUserFilter.as_view(), name='user-filter')
调用示例:请求/users/filter/?from_date=2024-01-01&to_date=2024-02-01即可获取对应日期区间的用户
其他日期区间筛选实现方式
除了当前使用的__range查询外,还有三种常用的筛选写法:
- 拆分区间条件,可灵活调整开闭区间,避免DateTime类型带时分秒导致的漏查问题:
from datetime import timedelta # 闭区间:包含from_date 0点到to_date 23:59:59的所有数据 User.objects.filter(created_at__gte=from_date, created_at__lt=to_date + timedelta(days=1)) - 按日期维度筛选,适合
created_at为DateTimeField类型,不需要精确到时分秒的场景:User.objects.filter(created_at__date__range=[from_date, to_date]) - 动态Q对象组合,适合需要和其他筛选条件动态拼接的场景:
from django.db.models import Q date_query = Q(created_at__gte=from_date) & Q(created_at__lte=to_date) # 可追加其他条件,比如筛选活跃用户 date_query &= Q(is_active=True) User.objects.filter(date_query)
额外优化建议
你当前的RegisteredUserFilterSerializer不需要写model = User属性,该属性只有ModelSerializer需要配置,普通Serializer仅做参数校验不需要关联模型。
内容的提问来源于stack exchange,提问作者Abinash Karki
相关产品推荐
相关产品推荐

