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

如何在Django的Movie模型中实现starring字段多选Actor?

实现Movie模型starring字段的Actor多选功能

问题背景

在crew应用中有继承自抽象模型Parent的Actor模型:

from django.db import models

# Create your models here.
class Parent(models.Model):
    # name=models.CharField(max_length=30,unique=True,default=None)
    name=models.CharField(max_length=30,unique=True,default=None)
    about=models.TextField(max_length=2000,blank=True,null=True)
    class Meta:
        abstract = True
    def __str__(self):
        return self.name
class Actor(Parent):
    slug=models.SlugField(max_length=50,unique=True)
    photo=models.ImageField(upload_to='crew/actor')

需要将其关联到movie应用中Movie模型的starring字段,实现多选Actor的功能。当前该字段使用ForeignKey仅支持单个Actor选择,Movie模型代码如下:

from django.db import models
from django.contrib.auth.models import User
from crew.models import *
from review_awards.models import *
# Create your models here.
class Movie(models.Model):
    name=models.CharField(max_length=100,unique=True,blank=True)
    slug=models.SlugField(max_length=100,unique=True,blank=True)
    year=models.CharField(max_length=5,blank=True)
    language=models.CharField(max_length=50,blank=True)
    poster=models.ImageField(upload_to='movies/poster')
    cover=models.ImageField(upload_to='movies/cover',null=True)
    duration=models.CharField(max_length=50,default=None)
    streaming=models.ForeignKey(Streaming,on_delete=models.CASCADE,blank=True,null=True)
    ott=models.TextField(max_length=50,blank=True,null=True)
    starring=models.ForeignKey(Actor,on_delete=models.CASCADE,related_name='actor',blank=True,null=True)
    director=models.ForeignKey(Director,on_delete=models.CASCADE,blank=True,null=True)
    cinematographer=models.ForeignKey(Cinematographer,on_delete=models.CASCADE,null=True,blank=True)
    writer=models.CharField(max_length=100,blank=True)
    based =models.CharField(max_length=100,blank=True,null=True)
    genre=models.CharField(max_length=100,blank=True)
    awards=models.ForeignKey(Award,on_delete=models.CASCADE,null=True,blank=True)
    critic_reviews=models.ForeignKey(Critic_Review,on_delete=models.CASCADE,null=True,blank=True)
    audience_reviews=models.ForeignKey(Audience_Review,on_delete=models.CASCADE,null=True,blank=True)
    rating=models.CharField(max_length=20,blank=True)
    certification=models.ForeignKey(Certification,on_delete=models.CASCADE,null=True,blank=True)
    synopsis=models.TextField(max_length=1000,blank=True)
    trailer=models.TextField(max_length=50,blank=True)
    def __str__(self):
        return self.name

解决方案

1. 替换字段类型为ManyToManyField

将Movie模型中的starring字段从ForeignKey改为ManyToManyField:

# 替换前
starring=models.ForeignKey(Actor,on_delete=models.CASCADE,related_name='actor',blank=True,null=True)

# 替换后
starring=models.ManyToManyField(Actor, related_name='starred_movies', blank=True)
  • ManyToManyField无需设置on_delete参数,多对多关系的关联数据删除逻辑由Django自动处理。
  • 修改related_name为starred_movies,语义更清晰,后续可通过actor.starred_movies.all()快速查询该演员参演的所有电影。

2. 执行数据库迁移

修改模型后,生成并应用迁移文件以更新数据库结构:

python manage.py makemigrations
python manage.py migrate

3. 优化Admin界面(可选)

若要在Django后台更便捷地选择多个Actor,可在Movie的Admin类中添加分栏选择配置:

from django.contrib import admin
from .models import Movie

class MovieAdmin(admin.ModelAdmin):
    filter_horizontal = ('starring',)  # 水平分栏展示选择器
    # 也可使用 filter_vertical = ('starring',) 垂直分栏

admin.site.register(Movie, MovieAdmin)

关联数据查询示例

  • 获取某部电影的所有主演:movie.starring.all()
  • 获取某演员参演的所有电影:actor.starred_movies.all()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 21:00:28