You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 02:45:01