Django如何通过关联模型查询用户所选课程的全部作业?
Django ORM 获取指定用户选课对应全部作业实现
基于你给出的模型关联关系,有3种常用实现方式,按性能优先级排序如下:
最优方案:跨表直接过滤(单次JOIN查询,性能最高)
利用Django ORM双下划线跨关联关系过滤的能力,直接从Homework表出发关联过滤符合条件的记录,不需要额外中间查询:# 先获取目标用户实例,替换成你实际的用户筛选逻辑 target_user = User.objects.get(id=目标用户ID) # 直接查询所有归属课程包含该用户的作业 all_related_homeworks = Homework.objects.filter(course__students=target_user)写法逻辑:
Homework通过外键course关联Course表,Course通过多对多字段students关联User表,双下划线course__students可以直接完成两张关联表的条件穿透。如果存在作业重复返回的情况,在查询末尾追加.distinct()即可去重。次选方案:通过用户所属课程集合IN查询
如果你后续逻辑还需要复用该用户的选课列表,可以先取出用户关联的课程,再通过course__in过滤作业:target_user = User.objects.get(id=目标用户ID) # 取用户关联的所有课程 user_courses = target_user.student_courses.all() # 过滤作业 all_related_homeworks = Homework.objects.filter(course__in=user_courses)注意:如果用户关联课程数量极多,IN子句查询性能会比第一种JOIN写法稍差。
预取优化方案:适合需要同时操作用户、课程、作业数据的场景
如果你需要同时拿到用户信息、用户所选课程、每门课的作业,可以用Prefetch提前预取关联数据,避免循环查询产生的N+1问题:from django.db.models import Prefetch target_user = User.objects.prefetch_related( Prefetch('student_courses__course_homeworks') ).get(id=目标用户ID) # 组装所有作业 all_related_homeworks = [] for course in target_user.student_courses.all(): all_related_homeworks.extend(course.course_homeworks.all())
❌ 避坑提醒:不要直接无预取循环遍历用户课程查作业,这种写法每遍历一门课就会发一次SQL查询,用户选课越多性能越差:
# 反面示例 禁止使用 bad_result = [] for course in target_user.student_courses.all(): bad_result.extend(list(course.course_homeworks.all()))
内容的提问来源于stack exchange,提问作者ParsaAi
相关产品推荐
相关产品推荐

