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

Django课程详情页上下课程功能报错:404及QuerySet属性缺失

问题分析与解决方案

核心错误原因

1. QuerySet属性错误

你在代码里先通过course = Courses.objects.get(id=id)获取了单个课程实例,但随后又用course = Courses.objects.filter(status=True)将变量course重新赋值为QuerySet(课程集合),导致后续调用course.counted_views时触发错误——QuerySet是多对象集合,没有单个实例的counted_views属性。

2. 404错误的隐藏原因

全局try-except块捕获了所有异常(包括课程不存在、上下课程id无效、索引越界等),直接返回404页面,掩盖了真实错误;同时当当前课程状态为False时,会出现在id_list中找不到id的情况,也会触发404。

修复后的代码实现

views.py 修正版

from django.shortcuts import render, get_object_or_404

def course_detail(request, id):
    # 获取当前激活课程,不存在直接返回404
    course = get_object_or_404(Courses, id=id, status=True)
    
    # 获取所有激活课程并按id排序(可按需替换为created_date等排序字段)
    active_courses = Courses.objects.filter(status=True).order_by('id')
    id_list = list(active_courses.values_list('id', flat=True))
    current_index = id_list.index(id)
    
    # 处理上/下课程逻辑,避免索引越界
    previous_course = None
    next_course = None
    
    if len(id_list) > 1:
        if current_index > 0:
            previous_course = Courses.objects.get(id=id_list[current_index - 1])
        if current_index < len(id_list) - 1:
            next_course = Courses.objects.get(id=id_list[current_index + 1])
    
    # 更新课程浏览量
    course.counted_views += 1
    course.save()
    
    context = {
        'course': course,
        'next_course': next_course,
        'previous_course': previous_course,
    }
    return render(request, "courses/course-details.html", context=context)

关键优化点

  • 变量名区分:用active_courses存储激活课程集合,避免覆盖单个课程实例course
  • 显式404处理:使用get_object_or_404替代原生get(),自动处理课程不存在的情况,无需手动捕获异常
  • 避免索引越界:增加课程数量判断,处理仅有单个课程的场景
  • 性能优化:用values_list直接提取id列表,比遍历实例更高效
  • 排序稳定:给active_courses加上order_by,保证id列表的顺序可预期(默认排序不具备稳定性)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 12:05:23