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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 02:45:48