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

如何计算Django中DurationField的总时长并解决类型运算报错

问题原因分析
  • 没有正确导入Django的Sum聚合函数,误用到了Python内置的sum()方法,内置sum不支持直接处理Django查询字段的字符串参数,是报错的核心原因
  • 聚合查询的写法错误:aggregate()返回的是字典格式结果,不能用.duration属性访问值
  • 逻辑冗余:不需要循环逐个查询每个视频的时长再累加,可以直接通过ORM关联查询一次性统计总时长,效率更高
修复后的实现方案

首先先导入Django聚合依赖:

from django.db.models import Sum

方案1:一次性关联查询(推荐,性能更高)

直接通过外键关联跨表查询,一次拿到指定模块下所有视频的总时长:

# 关联查询指定模块下所有未删除视频的总时长,软删除字段根据实际字段名调整
total_duration = VideoDetails.objects.filter(
    video__coursemoduletvideos__module_id=o,
    is_deleted=False,
    video__is_deleted=False,
    video__coursemoduletvideos__is_deleted=False
).aggregate(total=Sum('duration'))['total']

print(total_duration)
# 结果为datetime.timedelta类型,可直接调用方法获取数值:
# 总秒数:total_duration.total_seconds()
# 总分钟数:total_duration.total_seconds() // 60

方案2:原有循环写法的修复(不推荐,多次查询性能差)

如果要保留原循环逻辑,修改如下:

z = CourseModuleVideos.objects.filter(module_id=o, is_deleted=False)
total_duration = 0
for zo in z:
    print('o', zo.video_id)
    # 一对一关系直接get获取对应时长即可,无需聚合
    video_detail = VideoDetails.objects.get(video=zo.video_id, is_deleted=False)
    total_duration += video_detail.duration
print(total_duration)
额外说明

DurationField聚合后的结果是Python标准库的datetime.timedelta类型,可以直接通过.days、.seconds、total_seconds()等属性获取对应时间数值,也可以直接和其他timedelta类型做加减运算。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 12:36:03