Python Django无向唯一组合

Python Django无向唯一组合,python,django,model,unique-constraint,Python,Django,Model,Unique Constraint,我想在集合的所有成员之间建立成对关系的模型 class Match(models.Model): foo_a = models.ForeignKey(Foo, related_name='foo_a') foo_b = models.ForeignKey(Foo, related_name='foo_b') relation_value = models.IntegerField(default=0) class Meta: unique_t

我想在集合的所有成员之间建立成对关系的模型

class Match(models.Model):

    foo_a = models.ForeignKey(Foo, related_name='foo_a')
    foo_b = models.ForeignKey(Foo, related_name='foo_b')

    relation_value = models.IntegerField(default=0)

    class Meta:
        unique_together = ('ingredient_a', 'ingredient_b')
当我添加一对a-B时,它成功地阻止我再次添加a-B,但不会阻止我添加B-a

我试着跟着,但没用

unique_together = (('ingredient_a', 'ingredient_b'), ('ingredient_b', 'ingredient_a'))
编辑:
我需要每对项目的关系值都是唯一的

如果你定义了一个像你定义的那样的模型,它不仅仅是一个外键,它被称为多个关系

在django文档中,明确定义了不能为多个关系包含“唯一在一起”约束

从文件来看

一个ManyToManyField不能同时包含在unique_中。现在还不清楚这到底意味着什么!如果需要验证与ManyToManyField相关的唯一性,请尝试使用信号或显式直通模型

编辑

经过大量的搜索和一些尝试和错误,最后我想我已经找到了一个解决方案为您的情况。是的,正如你所说,目前的模式并不像我们都认为的那么琐碎。在这种情况下,多对多关系不是我们需要推进的讨论。解决方案是,或者我认为解决方案是模型清洁方法:


有关模型清理方法的更多详细信息,请参阅我已覆盖对象的save方法以每次保存2对。如果用户想要添加a-B对,则会自动添加具有相同参数的记录B-a

注意:此解决方案会影响查询速度。对于我的项目来说,这不是一个问题,但需要加以考虑


编辑:当然,更新和删除方法也需要重写。

我希望每个给定的两项的关系值都是唯一的。这意味着您需要将多个关系限制为一次只包含一个项目,据我所知,这并不简单。您的编辑确实可以防止不一致。谢谢你的意见。我通过创建冗余对A-B,B-A解决了这个问题。该表将不用于生产查询,而仅用于构建混淆矩阵以备将来使用,因此性能不是问题。我仍然想知道,如果必须考虑性能,这两种方法中哪一种会更好。您的方法的优点是不需要覆盖更新和删除方法。
class Match(models.Model):
    foo_a = models.ForeignKey(Foo, related_name='foo_a')
    foo_b = models.ForeignKey(Foo, related_name='foo_b')

    def clean(self):
        a_to_b = Foo.objects.filter(foo_a = self.foo_a, foo_b = self.foo_b)
        b_to_a = Foo.objects.filter(foo_a = self.foo_b, foo_b = self.foo_a) 

        if a_to_b.exists() or b_to_a.exists():
            raise ValidationError({'Exception':'Error_Message')})
def save(self, *args, **kwargs):
    if not Match.objects.filter(foo_a=self.foo_a, foo_b=self.foo_b).exists():
        super(Match, self).save(*args, **kwargs)
    if not Match.objects.filter(foo_a=self.foo_b, foo_b=self.foo_a).exists():
        Match.objects.create(foo_a=self.foo_b, foo_b=self.foo_a, bar=self.bar)