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

Django中艺人视频关联查询及中间类创建方法咨询

Django 模型与视图问题解答

1. 在views.py中实现点击艺人展示其专属视频的查询逻辑

给你两种常用实现方式,选适合你项目风格的就行:

函数视图写法

from django.shortcuts import get_object_or_404, render
from .models import Artist, Video

def artist_videos(request, artist_id):
    # 获取指定艺人,找不到就返回404页面
    artist = get_object_or_404(Artist, id=artist_id)
    # 直接通过多对多关联拿到该艺人的所有视频
    videos = artist.artist_videos.all()
    # 把数据传给模板渲染
    return render(request, 'your_template.html', {'artist': artist, 'videos': videos})

然后在urls.py配置对应路由:

path('artist/<int:artist_id>/videos/', views.artist_videos, name='artist_videos'),

模板里直接循环videos就能展示内容了。

类视图写法(更简洁)

用Django自带的DetailView,它会自动处理对象获取逻辑:

from django.views.generic.detail import DetailView
from .models import Artist

class ArtistVideoDetailView(DetailView):
    model = Artist
    template_name = 'your_template.html'
    context_object_name = 'artist'

路由配置:

path('artist/<int:pk>/videos/', ArtistVideoDetailView.as_view(), name='artist_videos'),

模板里直接用{{ artist.artist_videos.all }}遍历视频即可。

2. 当前模型存在的几个小问题

我帮你梳理了几个需要优化的点:

  • Artist的图片上传路径:upload_to='media'会把图片存在MEDIA_ROOT/media/下,有点冗余,建议改成upload_to='artist_pics'这类更清晰的路径,避免和默认media目录混淆。
  • Video的默认封面:video_image默认值是image.png,要确保这个文件存在于MEDIA_ROOT或STATIC_ROOT中,否则页面渲染时会出现图片加载失败的问题。
  • Video的描述字段:用TextField却加了max_length=100有点矛盾——TextField是用来存长文本的,如果是短描述,不如换成CharField(max_length=100);如果需要存长内容,就删掉max_length限制。
  • Video的发布时间:auto_now=True会在每次保存视频(比如修改信息)时更新时间,如果你要的是仅创建时记录的发布时间,应该改成auto_now_add=True。
  • 视频内容完整性:video_file和video_embed_link都允许为空,最好加个验证确保至少填其中一个,避免出现无内容的空视频。可以重写模型的clean()方法:
from django.core.exceptions import ValidationError

class Video(models.Model):
    # ... 其他字段 ...
    def clean(self):
        super().clean()
        if not self.video_file and not self.video_embed_link:
            raise ValidationError("必须上传视频文件或填写嵌入链接")

3. 是否需要创建中间类?

什么时候需要?

如果艺人与视频的关系只需要“关联”,不需要额外信息(比如视频被艺人收录的时间、在艺人列表中的排序权重等),那默认的多对多关系就足够,不需要自定义中间类。

但如果需要在关联中存储额外字段,就必须创建自定义中间模型。

如何创建中间类并查询?

比如我们要添加“视频被艺人添加的时间”字段:

from django.db import models

# 自定义中间模型
class ArtistVideo(models.Model):
    artist = models.ForeignKey(Artist, on_delete=models.CASCADE)
    video = models.ForeignKey(Video, on_delete=models.CASCADE)
    added_date = models.DateTimeField(auto_now_add=True)  # 额外字段:视频被添加的时间

    class Meta:
        unique_together = ('artist', 'video')  # 避免同一个艺人重复关联同一个视频

# 修改Artist模型的多对多字段,指定关联的中间模型
class Artist(models.Model):
    artist_picture = models.ImageField(upload_to='artist_pics')
    artist_name = models.CharField(max_length=100)
    artist_videos = models.ManyToManyField(Video, through=ArtistVideo)
    def __str__(self):
        return self.artist_name

查询某艺人的所有视频

即使加了中间模型,原来的简单查询依然有效:

artist = get_object_or_404(Artist, id=1)
videos = artist.artist_videos.all()

如果要用到中间表的额外字段(比如按添加时间倒序排列),可以这样写:

videos = Video.objects.filter(artistvideo__artist=artist).order_by('-artistvideo__added_date')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 13:22:55