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

Django中如何按年份统计指定Tourist的所有Arrival记录?

Django按年份统计指定游客的抵达记录问题

模型定义

class Tourist(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)

class Etablissement(models.Model):    
    name = models.CharField(max_length=30)

class Arrival(models.Model):
    tourist = models.ForeignKey(Tourist, on_delete=models.CASCADE)
    place = models.ForeignKey(Etablissement, on_delete=models.CASCADE)
    # 注:原模型需包含arrival_date字段,否则无法按年份分组

需求与错误场景

需要统计指定Tourist的所有Arrival记录并按年份分组,尝试的代码如下:

def detailTourist(request, id):
    touriste = Tourist.objects.get(id=id)
    datas = Arrival.objects.annotate(year=TruncYear('arrival_date')).values('year').annotate(total=Arrival.objects.filter(tourist=touriste)).order_by()

运行后出现错误:sub-select returns 19 columns - expected 1,原因是第二个annotate中直接传入了完整的Arrival查询集,而annotate需要的是聚合函数(如统计数量的Count),而非全字段的查询结果。

正确实现方式

方式一:先过滤再分组统计

from django.db.models import Count
from django.db.models.functions import TruncYear

def detailTourist(request, id):
    touriste = Tourist.objects.get(id=id)
    # 先筛选当前游客的抵达记录,再按年份分组统计数量
    datas = Arrival.objects.filter(tourist=touriste)\
        .annotate(year=TruncYear('arrival_date'))\
        .values('year')\
        .annotate(total=Count('id'))\
        .order_by('year')

方式二:通过反向关联查询

利用Django的反向关联特性(touriste.arrival_set)直接获取该游客的所有抵达记录,再进行分组统计:

from django.db.models import Count
from django.db.models.functions import TruncYear

def detailTourist(request, id):
    touriste = Tourist.objects.get(id=id)
    datas = touriste.arrival_set\
        .annotate(year=TruncYear('arrival_date'))\
        .values('year')\
        .annotate(total=Count('id'))\
        .order_by('year')

代码说明

  1. 先用filter(或反向关联)筛选出目标游客的所有Arrival记录,避免全局查询带来的性能问题。
  2. TruncYear('arrival_date')用于提取arrival_date字段的年份部分,作为分组依据。
  3. values('year')指定按年份分组。
  4. Count('id')统计每组内的记录数量,将结果存入total字段。
  5. order_by('year')确保结果按年份升序排列(可改为'-year'实现降序)。

内容的提问来源于stack exchange,提问作者Etsè FIATSI

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 18:45:46