Django如何将指定日期前30天数据按周分组返回?基于DRF实现
实现方案
以下是基于Django Rest Framework的完整实现逻辑:
1. 前置依赖导入
from datetime import datetime, timedelta from django.utils import timezone from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import serializers from .models import Car
2. 定义Car序列化器
class CarSerializer(serializers.ModelSerializer): class Meta: model = Car fields = ['id', 'name', 'model', 'date']
3. 视图核心逻辑
class CarGroupByWeekView(APIView): def get(self, request): # 1. 接收并校验日期参数 date_str = request.query_params.get('date') if not date_str: return Response({"error": "请传入日期参数,格式为YYYY-MM-DD"}, status=400) try: query_date = datetime.strptime(date_str, "%Y-%m-%d").date() except ValueError: return Response({"error": "日期格式错误,请使用YYYY-MM-DD格式"}, status=400) # 2. 计算30天时间范围,兼容时区配置 if timezone.is_naive(datetime.now()): start_datetime = datetime.combine(query_date - timedelta(days=30), datetime.min.time()) end_datetime = datetime.combine(query_date, datetime.max.time()) else: start_datetime = timezone.make_aware(datetime.combine(query_date - timedelta(days=30), datetime.min.time())) end_datetime = timezone.make_aware(datetime.combine(query_date, datetime.max.time())) # 3. 过滤符合时间范围的Car数据 car_queryset = Car.objects.filter(date__range=(start_datetime, end_datetime)).order_by('date') serialized_cars = CarSerializer(car_queryset, many=True).data # 4. 按每7天分组(从30天前的起始日期开始计算分组) groups = {} start_date = start_datetime.date() for car in serialized_cars: car_date = datetime.fromisoformat(car['date']).date() # 计算当前日期和起始日期的天数差,按7天取整作为分组标识 diff_days = (car_date - start_date).days group_key = diff_days // 7 # 生成分组的时间范围描述 group_start = start_date + timedelta(days=group_key*7) group_end = group_start + timedelta(days=6) group_name = f"{group_start} 至 {group_end}" if group_name not in groups: groups[group_name] = [] groups[group_name].append(car) # 5. 整理成列表格式返回 result = [{"week_range": k, "cars": v} for k, v in groups.items()] return Response(result)
可选:按自然周分组实现
如果你需要按自然周(周一到周日)分组,可直接用Django ORM的TruncWeek方法简化逻辑:
from django.db.models.functions import TruncWeek # 省略前面参数校验和时间范围过滤步骤 car_queryset = Car.objects.filter(date__range=(start_datetime, end_datetime))\ .annotate(week_start=TruncWeek('date'))\ .order_by('week_start', 'date') # 按week_start字段分组即可 groups = {} for car in car_queryset: week_start = car.week_start.date() week_end = week_start + timedelta(days=6) group_name = f"{week_start} 至 {week_end}" if group_name not in groups: groups[group_name] = [] groups[group_name].append(CarSerializer(car).data)
TruncWeek默认将日期截断为当周周一,符合国内常用的周起始规则。
内容的提问来源于stack exchange,提问作者sarath sathyan
相关产品推荐
相关产品推荐

