如何将JavaScript编写的过滤函数功能迁移实现为Django Python代码
问题原因与修复实现
报错根因
你当前代码运行报错的核心原因有2个:
- 变量名拼写不一致:你外层定义的时长列表变量名为
timeList,但timeAttendees函数内部引用的是time_list,Python大小写敏感,会找不到对应变量 - 你没有提前加载当前会议的
meeting_times数据集,函数内部循环的对象不存在,同时attendee模型的user字段允许为null,没有做空值判断会触发属性不存在错误
另外你原JS的过滤逻辑可以简化:timeAttendees(element.user.id) <= 0 || (element.absent && this.timeAttendees(element.user.id) <= 0) 等价于只要timeAttendees(element.user.id) <= 0就满足条件,两种写法结果完全一致。
可直接运行的实现代码
# 1. 提前获取当前会议的所有时长记录 meeting_times = meeting.meeting_times.all() # 2. 定义计算单个用户参会总时长的函数 def calc_user_total_time(attendee): # 处理user为空的情况,直接返回0 if not attendee.user: return 0 total_time = 0 for time_item in meeting_times: if time_item.user.id == attendee.user.id: total_time += time_item.time return total_time # 3. 过滤符合条件的缺席参会人,完全对齐JS逻辑 absent_attendees = [ att for att in meeting.attendees.all() if calc_user_total_time(att) <= 0 # 如果你要严格保留原JS的冗余判断,可替换为下面的条件: # if calc_user_total_time(att) <=0 or (att.absent and calc_user_total_time(att) <=0) ]
更高效的Django原生实现(推荐)
不用循环遍历,用Django ORM的聚合能力直接查询,性能更高:
from django.db.models import Sum, Coalesce absent_attendees = meeting.attendees.annotate( total_time=Coalesce(Sum('user__meeting_times__time'), 0) ).filter(total_time__lte=0)
注:该写法要求meeting_times模型关联User的related_name为meeting_times,如果你的模型定义里related_name不一致,替换成对应的值即可。
内容的提问来源于stack exchange,提问作者Gamoxion
相关产品推荐
相关产品推荐

