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

Django:统计指定日期范围内唯一起讫点对的行程次数

解决行程监控应用的起点-终点对统计需求

嘿,我来帮你搞定这个行程统计的需求!首先先补全一下你的模型(看起来你没写完Trip的关联字段,我假设是这样的):

class Location(models.Model):
    name = models.CharField(max_length=50, unique=True)
    # 你的其他字段...

class Trip(models.Model):
    ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE)  # 假设Ticket是你定义的票据模型
    origin = models.ForeignKey(Location, on_delete=models.CASCADE, related_name='origin_trips')
    destination = models.ForeignKey(Location, on_delete=models.CASCADE, related_name='destination_trips')
    trip_date = models.DateField()  # 核心:用来筛选日期范围的字段,用DateTimeField也一样能用
    # 你的其他字段...

接下来分两种常见场景给你解决方案:

场景1:区分往返行程(A→B和B→A算不同路线)

用Django ORM的values()+annotate()就能轻松实现分组统计,还能直接关联获取地点名称:

from django.db.models import Count
from datetime import date

# 定义你要统计的日期范围
start_date = date(2024, 1, 1)
end_date = date(2024, 12, 31)

# 执行统计:筛选日期→按起点+终点分组→统计每组行程数
trip_stats = Trip.objects.filter(
    trip_date__range=(start_date, end_date)
).values(
    'origin__name', 'destination__name'  # 直接用地点名称分组,不用后续再查Location
).annotate(
    trip_count=Count('id')  # 统计每组的行程数量
).order_by('-trip_count')  # 可选:按行程数从多到少排序

遍历结果的示例:

for stat in trip_stats:
    print(f"从{stat['origin__name']}到{stat['destination__name']}: {stat['trip_count']}次行程")

如果需要保留地点的ID(比如后续要做关联操作),可以调整values()的参数:

trip_stats = Trip.objects.filter(
    trip_date__range=(start_date, end_date)
).values(
    'origin_id', 'origin__name', 'destination_id', 'destination__name'
).annotate(
    trip_count=Count('id')
)

场景2:往返行程视为同一组(A→B和B→A算同一条路线)

如果需要把往返路线合并统计,Django ORM直接做有点局限,我们可以先按场景1拿到统计结果,再在Python层面处理:

from collections import defaultdict

# 先拿到场景1的trip_stats结果
combined_stats = defaultdict(int)
for stat in trip_stats:
    # 生成排序后的键,让('A','B')和('B','A')变成同一个键
    route_key = tuple(sorted((stat['origin__name'], stat['destination__name'])))
    combined_stats[route_key] += stat['trip_count']

# 转换成更易读的格式
final_stats = [
    {'route': f"{k[0]} ↔ {k[1]}", 'total_trips': v}
    for k, v in combined_stats.items()
]

注意事项

  • 确保你的Trip模型里有日期字段(不管是DateField还是DateTimeField,__range筛选器都能生效);
  • 如果你的起点/终点允许为空,空值也会被当成一个独立的分组,要是想排除空值,在filter()里加origin__isnull=False, destination__isnull=False即可。

内容的提问来源于stack exchange,提问作者Josh21

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:17:14