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

如何在Django中创建关联外键的Video模型表单:默认Course并显示对应Section

如何创建满足需求的Video模型表单?

需求说明:创建Video模型的表单时,默认关联指定Course,且仅展示该Course对应的SectionVideo选项。现有模型定义如下:

现有模型代码

Course模型

class Course(models.Model):
    instructor = models.ForeignKey(UserProfile,on_delete=models.CASCADE) 
    name = models.CharField(max_length = 50 , null = False,unique = True)
    slug = models.CharField(max_length = 50 , null = False , unique = True)

SectionVideo模型

class SectionVideo(models.Model):
    course = models.ForeignKey(Course , null = False , on_delete=models.CASCADE)
    name = models.CharField(max_length = 50 , null = False)
    slug = models.CharField(max_length = 50 , null = False )
    serial_number = models.IntegerField(null=False)

Video模型

class Video(models.Model):
    section_video = models.ForeignKey(SectionVideo , null = False , on_delete = models.CASCADE)
    course = models.ForeignKey(Course , null = False , on_delete = models.CASCADE)
    title  = models.CharField(max_length = 100 , null = False)
    video_description = models.CharField(max_length = 500 , null = True)

实现步骤

1. 编写表单类(forms.py)

通过ModelForm创建表单,重写__init__方法实现:

  • 接收指定Course参数,设置为表单默认值
  • 过滤section_video选项,仅显示当前Course下的章节
from django import forms
from .models import Video, SectionVideo

class VideoForm(forms.ModelForm):
    class Meta:
        model = Video
        fields = ['section_video', 'course', 'title', 'video_description']
        # 将course设为隐藏字段,避免用户修改默认关联的课程
        widgets = {
            'course': forms.HiddenInput(),
        }

    def __init__(self, *args, **kwargs):
        # 从参数中提取指定的Course
        course = kwargs.pop('course', None)
        super().__init__(*args, **kwargs)
        if course:
            # 设置course字段的初始值
            self.fields['course'].initial = course
            # 过滤章节选项,仅展示当前课程下的SectionVideo
            self.fields['section_video'].queryset = SectionVideo.objects.filter(course=course)
            # 优化章节字段的显示标签
            self.fields['section_video'].label = f"章节(所属课程:{course.name})"

2. 在视图中传递指定Course并实例化表单(views.py)

从URL参数中获取目标Course,将其传入表单初始化,处理表单的提交逻辑:

from django.shortcuts import get_object_or_404, render, redirect
from .models import Course, Video
from .forms import VideoForm

def create_video(request, course_slug):
    # 通过slug获取指定课程
    course = get_object_or_404(Course, slug=course_slug)
    if request.method == 'POST':
        form = VideoForm(request.POST, course=course)
        if form.is_valid():
            form.save()
            # 保存后跳转至课程详情页(可根据需求修改跳转目标)
            return redirect('course_detail', slug=course_slug)
    else:
        # GET请求时,传入course初始化表单
        form = VideoForm(course=course)
    return render(request, 'create_video.html', {'form': form, 'course': course})

3. 模板中渲染表单(create_video.html)

渲染表单并展示当前关联的课程信息:

<h2>为课程 {{ course.name }} 添加视频</h2>
<form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">保存视频</button>
</form>

可选优化建议

Video模型中的course字段存在冗余,因为可通过section_video.course获取关联课程。可以修改模型去掉冗余字段,简化逻辑:

class Video(models.Model):
    section_video = models.ForeignKey(SectionVideo, null=False, on_delete=models.CASCADE)
    title = models.CharField(max_length=100, null=False)
    video_description = models.CharField(max_length=500, null=True)

    # 通过属性快速获取关联课程
    @property
    def course(self):
        return self.section_video.course

修改后,表单中可移除course字段,进一步简化代码。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 09:35:23