有没有一种方法可以在2个字段上创建唯一的ID?

Pit*_*all 14 python django django-models

这是我的模型:

class GroupedModels(models.Model):
    other_model_one = models.ForeignKey('app.other_model')
    other_model_two = models.ForeignKey('app.other_model')
Run Code Online (Sandbox Code Playgroud)

本质上,我想要的是other_model在此表中唯一。这意味着,如果存在other_model_oneid 为的记录,则123我不应该再创建other_model_twoID为as的另一条记录123。我可以覆盖clean我的猜测,但是我想知道django是否内置了某些东西。

我在PSQL中使用版本2.2.5。

编辑:这不是一个不合时宜的情况。如果我用other_model_one_id=1和其他添加一条记录other_model_two_id=2,我应该不能用other_model_one_id=2和其他添加另一条记录。other_model_two_id=1

dan*_*era 10

我在这里解释了几个选项,也许其中一个或组合可能对您有用。

覆写 save

您的约束是业务规则,您可以重写save方法以保持数据一致:


class GroupedModels(models.Model): 
    # ...
    def clean(self):
        if (self.other_model_one.pk == self.other_model_two.pk):
            raise ValidationError({'other_model_one':'Some message'}) 
        if (self.other_model_one.pk < self.other_model_two.pk):
            #switching models
            self.other_model_one, self.other_model_two = self.other_model_two, self.other_model_one
    # ...
    def save(self, *args, **kwargs):
        self.clean()
        super(GroupedModels, self).save(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

变更设计

我提供了一个易于理解的示例。让我们假设这种情况:

class BasketballMatch(models.Model):
    local = models.ForeignKey('app.team')
    visitor = models.ForeignKey('app.team')
Run Code Online (Sandbox Code Playgroud)

现在,您要避免一个团队与自己进行比赛,而A团队只能与B团队一起比赛一次(几乎是您的规则)。您可以将模型重新设计为:

class BasketballMatch(models.Model):
    HOME = 'H'
    GUEST = 'G'
    ROLES = [
        (HOME, 'Home'),
        (GUEST, 'Guest'),
    ]
    match_id = models.IntegerField()
    role = models.CharField(max_length=1, choices=ROLES)
    player = models.ForeignKey('app.other_model')

    class Meta:
      unique_together = [ ( 'match_id', 'role', ) ,
                          ( 'match_id', 'player',) , ]
Run Code Online (Sandbox Code Playgroud)

ManyToManyField.symmetrical

这看起来像一个对称问题,django可以为您解决。无需创建GroupedModels模型,只需在其上创建一个ManyToManyField字段即可OtherModel

from django.db import models
class OtherModel(models.Model):
    ...
    grouped_models = models.ManyToManyField("self")
Run Code Online (Sandbox Code Playgroud)

这就是django在这些情况下内置的内容。