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
相关产品推荐
相关产品推荐

