You need to enable JavaScript to run this app. 如何简化Django模型代码,实现多季多集影视剧的admin后台按需管理
优惠活动
大模型
产品
解决方案
定价
更多

如何简化Django模型代码,实现多季多集影视剧的admin后台按需管理

影视站点Django模型重构方案

核心设计思路

彻底抛弃“模型内硬编码单集字段、独立模型对应单季”的冗余实现,基于Django原生外键关联搭建三层标准化结构,100%兼容原有所有功能,同时支持无上限的季、集数扩展,可直接在Admin后台按需新增条目。

  • 模型结构完全符合关系型数据库设计规范,没有冗余存储字段
  • 无集数、季数的存储上限,不管是小众短集剧还是长篇多季剧都能适配
  • Admin后台操作逻辑和原有使用习惯一致,不需要重新适应
  • 所有原有业务逻辑不需要改动,可实现平滑迁移

第一步:清理原有TvShow模型的冗余字段

直接删除TvShow模型里硬编码的episode1到episode10共10个URL字段,其余所有原有字段、自定义配置完全原封不动保留,不改动任何已有逻辑:

from django.db import models
from taggit.managers import TaggableManager
# 你原有编写的published自定义管理器直接导入沿用,无改动
from .managers import PublishedManager

class TvShow(models.Model):
    # 以下字段完全和原实现保持一致
    title = models.CharField(max_length=200)
    slug = models.SlugField(max_length=200, unique=True)
    author = models.ForeignKey('auth.User', on_delete=models.CASCADE, related_name='tv_shows')
    body = models.TextField()
    imdb_rating = models.DecimalField(max_digits=3, decimal_places=1)
    publish = models.DateTimeField()
    status = models.CharField(max_length=10, choices=[('draft', '草稿'), ('published', '已发布')])
    views = models.PositiveIntegerField(default=0)
    tags = TaggableManager()

    # 原有管理器配置完全保留
    objects = models.Manager()
    published = PublishedManager()

注意:这部分操作不会影响原有代码中对TvShow模型的任何查询、调用逻辑,比如你之前写的TvShow.published.filter(status='published')这类代码可以直接运行,不需要修改。


第二步:新增通用Season模型(替代逐季建独立模型的冗余方案)

不需要为每一个季度单独写模型,建一个通用的Season模型通过外键关联到所属的电视剧,仅通过季序号区分不同季度即可:

class Season(models.Model):
    # 外键关联到对应的电视剧实例
    tv_show = models.ForeignKey(
        TvShow,
        on_delete=models.CASCADE,
        related_name='seasons'
    )
    # 季序号:填1代表第1季,填2代表第2季,支持任意数量的季度
    season_number = models.PositiveSmallIntegerField(help_text="季度序号")
    # 可选填的季标题,不需要可以留空
    title = models.CharField(max_length=200, blank=True)

    class Meta:
        # 同一个电视剧下,季号不允许重复
        unique_together = ('tv_show', 'season_number')
        # 默认按季号升序排列
        ordering = ['season_number']

    def __str__(self):
        return f"{self.tv_show.title} 第{self.season_number}季"

第三步:新增通用Episode模型(替代硬编码单集字段的方案)

用通用的Episode模型存储每一集的视频链接,通过外键关联到所属的季度,仅通过集序号区分单集,没有集数上限:

class Episode(models.Model):
    # 外键关联到所属的季度实例
    season = models.ForeignKey(
        Season,
        on_delete=models.CASCADE,
        related_name='episodes'
    )
    # 集序号:填1代表第1集,填2代表第2集,支持任意数量的单集
    episode_number = models.PositiveSmallIntegerField(help_text="集序号")
    # 存储单集的视频链接,替代原来硬编码的10个episode字段
    video_url = models.URLField(help_text="对应集数的视频播放链接")
    # 可选填的单集标题、简介,不需要可以留空
    title = models.CharField(max_length=200, blank=True)

    class Meta:
        # 同一个季度下,集号不允许重复
        unique_together = ('season', 'episode_number')
        # 默认按集号升序排列
        ordering = ['episode_number']

    def __str__(self):
        return f"{self.season} 第{self.episode_number}集"

第四步:配置Admin后台,实现可视化按需新增季、集

不需要写复杂的自定义Admin逻辑,通过Django原生的Inline组件配置,即可在编辑电视剧的页面直接新增季度、上传单集视频链接,操作路径和原来完全一致:

from django.contrib import admin
from .models import TvShow, Season, Episode

# 单集的内嵌编辑组件
class EpisodeInline(admin.TabularInline):
    model = Episode
    extra = 0  # 默认不显示空的新增行,需要时点击“新增另一个Episode”即可
    verbose_name = "单集"
    verbose_name_plural = "单集列表"

# 季度的内嵌编辑组件
class SeasonInline(admin.TabularInline):
    model = Season
    extra = 0
    # 季度编辑页内嵌单集编辑功能
    inlines = [EpisodeInline]
    verbose_name = "季度"
    verbose_name_plural = "季度列表"

@admin.register(TvShow)
class TvShowAdmin(admin.ModelAdmin):
    # 原有Admin配置完全保留,比如list_display、search_fields、list_filter等设置不需要改动
    inlines = [SeasonInline]

原有历史数据迁移说明

你之前存在episode1到episode10字段里的历史视频链接,可以写一次性Django数据迁移脚本,自动完成迁移:

  • 遍历所有TvShow实例,为每一个剧生成默认的第1季Season实例
  • 逐次读取原来硬编码的10个episode字段的URL,如果值不为空,就生成对应的Episode实例,把URL写入video_url字段,集号对应原来的字段序号
  • 迁移完成后就可以彻底移除那10个旧的硬编码字段,全流程不需要手动整理数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.06 19:06:03