主键上的 Django unique_together

Django unique_together on primary key

目前我有三个模型:

class Tutorial(models.Model):
    title = models.CharField(max_length=100)
    description = models.TextField()
    videos = models.ManyToManyField('TutorialVideo', through='TutorialVideoThrough', blank=True)


class TutorialVideo(models.Model):
    name = models.CharField(max_length=100)
    video = S3DirectField(dest='tutorial_vids')
    length = models.CharField("Length (hh:mm:ss)",max_length=100)
    tutorials = models.ManyToManyField(Tutorial, through='TutorialVideoThrough', blank=True)


class TutorialVideoThrough(models.Model):
    tutorial = models.ForeignKey(Tutorial, related_name='tutorial_video_through', blank=True, null=True)
    video = models.ForeignKey(TutorialVideo, related_name='video_tutorial_through', blank=True, null=True)
    order = models.IntegerField()

一个Tutorial可以通过TutorialVideoThrough有多个TutorialVideos。在 TutorialVideoThrough 上,我有一个 order 字段来决定视频的显示顺序。有没有办法验证没有重复的顺序整数?例如,如果我通过 TutorialVideoThrough 将两个 TutorialVideos 链接到一个教程,并且我将第一个视频作为顺序 1,那么我应该无法将第二个视频作为顺序 1。

我尝试在 TutorialVideoThrough 上使用 unique_together = ('id', 'order'),但没有成功。

如果您希望每个 order 对于每个 tutorial 都是唯一的,那么您需要

unique_together = (
    ('tutorial', 'order'),
)

您可能希望每个视频在每个教程中只出现一次。如果是这样,请将 ('tutorial', 'video') 添加到 unique_together

unique_together = (
    ('tutorial', 'order'),
    ('tutorial', 'video'),
)

请注意,您应该只在模型的一侧定义多对多关系。如果你有

class Tutorial(models.Model):
    videos = models.ManyToManyField('TutorialVideo', through='TutorialVideoThrough', blank=True, related_name='tutorials')

那么您应该从 TutorialVideo 模型中删除 tutorial 字段。

primary_key 始终是唯一的,因此您的 unique_together 对也将始终是唯一的。

如果一定要确保没有相同顺序的视频,首先要回答问题:关于什么?

如果您想在 Tutorial 中的 TutorialVideo 列表中具有唯一性,您的 unique_together 应该是:

unique_together = (('tutorial', 'order'),)

如果您希望在 TutorialVideo 中的 Tutorial 列表中具有唯一性,您的 unique_together 应该是:

unique_together = (('video', 'order'),)

但是将 order 设置为唯一并不是一个好主意,您在尝试重新排序字段时会遇到一些问题。