你能确保只有一个对象与另一个对象相关联才具有特定的字段集吗?

Can you make sure only one object related to another object has a certain field set?

我有一个名为 Video 的模型,它在另一个名为 Label 的模型上有相关对象。此处示例:

class Video(models.Model):
    pass


class Label(models.Model):
    video = models.ForeignKey(Video, related_name="labels")
    current = models.NullBooleanField()

我需要能够通过 my_video.labels.filter(current=True) 之类的操作找到视频上的当前标签,并且此查询应该只 return 一个标签,因此视频上应该只有一个标签将该字段设置为 True.

有没有办法在 model/db 上确保这一点?

谢谢

编辑:下面给出的答案正是实现了这一点。在下面添加一些 django 测试供其他人阅读作为证据:

class TestLabelIntegrity(TestCase):
    def test_a_video_can_have_only_one_current_label(self):
        video = Video.objects.create()
        label_1 = Label.objects.create(
            video=video,
            current=True
        )
        with self.assertRaises(IntegrityError):
            label_2 = Label.objects.create(
                video=video,
                current=True
            )

    def test_two_different_videos_can_each_have_current_layers(self):
        """ No assertions needed, just need to make sure no integrity errors are raised"""
        video_1 = Video.objects.create()
        label_1 = Label.objects.create(
            video=video_1,
            current=True
        )
        video_2 = Video.objects.create()
        label_2 = Label.objects.create(
            video=video_2,
            current=True
        )

我相信你可以使用 UniqueConstraint 解决这个问题。 使用它,您可以限制视频只有一个标签 current == True

您可以在模型 Meta 中定义 UniqueConstraint。 如果条件失败,您将在 save() 上收到数据库完整性错误。

在此处查看相关文档:

https://docs.djangoproject.com/en/4.0/ref/models/constraints/

class Label(models.Model):
    ...
    class Meta:
        constraints = [
            models.UniqueConstraint(
                fields=["current", "video"],
                condition=Q(current=True),
                name="unique_current_label",
            ),
        ]