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

Django模型过滤问题:如何让课时仅显示在所属对应课程中

问题描述

我在Lesson模型中设置了指向Course的外键,期望创建的课时仅能在所属的特定课程中查看,但目前出现了在课程1中创建的课时也会显示在课程2中的问题,请问该如何解决?


相关代码

views.py

def lessonpage(request):
    lesson = Lesson.objects.all()
    if request.user.is_authenticated:
        return render(request, "lessons/lessons.html", {'lessons': lesson})
    else:
        return redirect('loginpage')

def addlesson(request):
    if request.method == "POST":
        form = AddLessonForm(request.POST)
        if form.is_valid():
            form.save()
        return render(request, "lessons/successlessons.html", {'form1': form})
    form = AddLessonForm()
    return render(request, "lessons/addlessons.html", {'form': form})

def deletelessons(request, id):
    lesson = Lesson.objects.get(id=id)
    lesson.delete()
    return redirect("lessonspage")

models.py

from django.db import models

class Section(models.Model):
    nameofsection = models.CharField(max_length=50, default="")

    def __str__(self):
        return self.nameofsection

class Course(models.Model):
    ctitle = models.CharField(max_length=50, default="")
    cdescription = models.TextField(max_length=200, default="")
    #csection = models.ForeignKey(Section, on_delete=models.CASCADE)

    def __str__(self):
        return self.ctitle

    def __unicode__(self):
        return self.ctitle

    class Meta:
        db_table="courses"

class Lesson(models.Model):
    title = models.CharField(max_length=50, default="")
    description = models.TextField(max_length=200, default="")
    course = models.ForeignKey(Course, on_delete=models.CASCADE, blank=True, null=True)

    def __str__(self):
        return self.title

urls.py

path('course/', coursepage, name="coursepage"),
path('course/<int:pk>', CourseDetailView.as_view(), name='detailed'),
path('addcourse/', addcourse, name="addcoursepage"),
path('editcourse/<int:id>', updatecourse, name="editcoursepage"),
path('updatecourse/<int:id>', updatecourserecord, name="updatecourse"),
path('deletecourse/<int:id>', deletecourse, name="deletecourse"),

path('lessons', lessonpage, name="lessonspage"),
path('lessons/addlessons', addlesson, name="addlessonspage"),
path('deletelessons/<int:id>', deletelessons, name="deletelessons"),

解决方案

核心问题是当前lessonpage视图直接查询所有课时(Lesson.objects.all()),未按课程过滤。按以下步骤调整即可解决:

1. 修改课时列表视图,按课程过滤

更新lessonpage,让它接收课程ID参数,只返回对应课程的课时:

def lessonpage(request, course_id):
    # 过滤指定课程的课时
    lessons = Lesson.objects.filter(course_id=course_id)
    # 传递当前课程对象到模板,方便展示课程信息
    course = Course.objects.get(id=course_id)
    if request.user.is_authenticated:
        return render(request, "lessons/lessons.html", {'lessons': lessons, 'course': course})
    else:
        return redirect('loginpage')

2. 更新URL配置,传递课程ID

修改urls.py中的课时路由,增加课程ID参数:

# 替换原有lessons路由
path('lessons/<int:course_id>', lessonpage, name="lessonspage"),

3. 优化添加课时逻辑,强制关联指定课程

当前添加课时时可能未指定所属课程(course字段允许空),需调整确保课时关联到具体课程:

方式一:通过URL传递课程ID并自动绑定

修改addlesson视图,接收课程ID并自动设置关联:

def addlesson(request, course_id):
    course = Course.objects.get(id=course_id)
    if request.method == "POST":
        form = AddLessonForm(request.POST)
        if form.is_valid():
            # 先创建实例不保存,再绑定课程
            lesson = form.save(commit=False)
            lesson.course = course
            lesson.save()
            return redirect('lessonspage', course_id=course_id)
        return render(request, "lessons/successlessons.html", {'form1': form})
    # 初始化表单时默认填充当前课程
    form = AddLessonForm(initial={'course': course})
    return render(request, "lessons/addlessons.html", {'form': form, 'course': course})

同步更新添加课时的URL:

path('lessons/<int:course_id>/addlessons', addlesson, name="addlessonspage"),

方式二:在表单中隐藏课程字段

如果使用ModelForm,修改AddLessonForm将course设为隐藏字段,从模板传入课程ID:

# 假设AddLessonForm是ModelForm
class AddLessonForm(forms.ModelForm):
    class Meta:
        model = Lesson
        fields = ['title', 'description', 'course']
        widgets = {
            'course': forms.HiddenInput()
        }

然后在课程详情页的"添加课时"链接中带上课程ID:

<!-- 课程详情页模板 -->
<a href="{% url 'addlessonspage' course.id %}">添加课时</a>

4. 调整课程详情页的课时入口

在CourseDetailView对应的模板中,链接到该课程的专属课时页面:

<a href="{% url 'lessonspage' course.id %}">查看该课程的课时</a>

额外优化:禁止无归属的课时

可以移除Lesson模型中course字段的blank=True, null=True,强制课时必须关联课程:

class Lesson(models.Model):
    title = models.CharField(max_length=50, default="")
    description = models.TextField(max_length=200, default="")
    # 去掉空值允许,确保课时必须属于某课程
    course = models.ForeignKey(Course, on_delete=models.CASCADE)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 02:01:18