如何计算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
相关产品推荐
相关产品推荐

