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

Django查询关联视频报QuerySet无videos/videos_set属性错误

报错原因
  • 核心问题:你代码中curriculum = Curriculum.objects.filter(course=course)拿到的不是单个Curriculum模型实例,是filter()返回的QuerySet类型(即符合查询条件的多条Curriculum记录的集合)。反向关联属性(包括你配置的related_name="videos"、Django默认生成的video_set)仅能在单个模型实例上调用,直接在QuerySet集合上调用自然会触发属性不存在的报错。哪怕filter查询结果只有1条记录,返回值依然是QuerySet类型,不会自动变成单个实例。
  • 隐藏逻辑问题:未登录分支中写的course.videos.all()、Video.objects.filter(course=course)逻辑本身不成立,你的Video模型外键是关联Curriculum而非Course,Course模型没有配置直达Video的关联关系,这部分代码运行时也会报错。
修复方案

你的模型层级是Course 1对多 Curriculum 1对多 Video,即一个课程对应多个大纲,每个大纲对应多个视频,按以下步骤修正即可:

1. 修正基础查询逻辑

把原来直接在QuerySet上调关联属性的写法替换为跨关联查询,性能更高也不会触发类型错误:

# 已登录、未登录分支都先查当前课程下的所有大纲
curriculums = Curriculum.objects.filter(course=course)
# 跨关联查询所有属于这些大纲的视频,按序列号排序
videos = Video.objects.filter(curriculum__in=curriculums).order_by("serial_number")
video_count = videos.count()
lectures = videos.count()

如果你的页面需要按大纲分组展示视频,可以加预加载减少数据库查询,遍历单个大纲实例时再调用反向关联:

# 预加载所有大纲关联的视频,避免循环查询
curriculums = Curriculum.objects.filter(course=course).prefetch_related("videos")
# 遍历拿到单个大纲实例后,就可以正常调用.videos取关联视频
for item in curriculums:
    item_videos = item.videos.all().order_by("serial_number")

2. 修正单条视频查询逻辑

原来的get_or_create直接传入QuerySet作为curriculum参数会触发参数类型错误,需要调整查询条件,同时给非空字段补默认值避免新建记录时触发约束报错:

# 两个分支的单条视频查询都替换为以下逻辑
video, created = Video.objects.get_or_create(
    serial_number=serial_number,
    curriculum__in=curriculums,
    defaults={
        "curriculum": curriculums.first(),
        "video_id": "",
        "title": f"第{serial_number}讲"
    }
)

3. 额外注意点

你已经在Video的curriculum外键上配置了related_name="videos",反向关联查询直接用.videos即可,不需要再用Django默认生成的video_set,二者同时使用反而会造成关联命名冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 23:57:14