小编Ger*_*cer的帖子

Django在两个方向上唯一的共同约束

所以我有一些看起来像这样的模型

class Person(BaseModel):
    name = models.CharField(max_length=50)
    # other fields declared here...
    friends = models.ManyToManyField(
        to="self",
        through="Friendship",
        related_name="friends_to",
        symmetrical=True
    )

class Friendship(BaseModel):
    friend_from = models.ForeignKey(
        Person, on_delete=models.CASCADE, related_name="friendships_from")
    friend_to = models.ForeignKey(
        Person, on_delete=models.CASCADE, related_name="friendships_to")
    state = models.CharField(
        max_length=20, choices=FriendshipState.choices, default=FriendshipState.pending)
Run Code Online (Sandbox Code Playgroud)

基本上,我正在尝试模拟一种类似 Facebook 的好友场景,其中有不同的人,并且可以邀请任何其他人成为好友。这种关系是通过最后一个模型来表达的Friendship

到目前为止,一切都很好。但我想避免三种情况:

    1. 友谊不能在friend_fromfriend_to领域有同一个人
    1. Friendship一组两个朋友只允许使用一个。

我最接近的是将其添加到Friendship模型下:

class Meta:
    constraints = [
        constraints.UniqueConstraint(
            fields=['friend_from', 'friend_to'], name="unique_friendship_reverse"
        ),
        models.CheckConstraint(
            name="prevent_self_follow",
            check=~models.Q(friend_from=models.F("friend_to")),
        )
    ]
Run Code Online (Sandbox Code Playgroud)

这完全解决了情况1,避免某人与自己交朋友,使用CheckConstraint. 并部分解决了第二种情况,因为它避免了Friendships这样的两种情况:

p1 = Person.objects.create(name="Foo") …
Run Code Online (Sandbox Code Playgroud)

django django-models unique-constraint python-3.x

5
推荐指数
1
解决办法
2168
查看次数