我有一个看起来像这样的模型:
class Bar(models.Model):
foo1 = models.ForeignKey(Foo, related_name='bar_foo1')
foo2 = models.ForeignKey(Foo, related_name='bar_foo2')
class Meta:
unique_together = ('foo1', 'foo2')
问题是foo1
和foo2
在被颠倒时需要具有相同的行为。换句话说,它是这样的:"如果你喜欢foo1,你可能想要检查foo2 out",这应该反过来适用("如果你喜欢foo2,你可能想要检查foo1")。
所以我使用了ManyToMany字段而不是ForeignKey来使它们对称:
class Bar(models.Model):
foos = models.ManyToManyField(Foo)
使用信号确保永远不会超过2 foos
:
def foos_changed(sender, **kwargs):
if kwargs['instance'].foos.count() > 2:
raise ValidationError("You can't assign more than two foos.")
m2m_changed.connect(foos_changed, sender=Bar.foos)
然而,这会产生另一个问题,如果Foo
中的foos
被删除,Bar
就会停留在那里,但也应该删除(这已经解决了)通过在ForeignKeys中删除级联。)
我该如何解决这个问题?我可以让ForeignKeys对称吗?或者在ManyToMany中实现级联删除?或者还有另一种解决方法吗?
答案 0 :(得分:2)
之前我已经完成了这个,最简单的方法是为模型实例创建一个伪构造函数,确保第1项和第2项始终按顺序排列(我使用字母顺序,但你也可以使用id)独特性工作ootb。
在查找中,您只需在foo1或foo2中查找您的项目,因为您不介意关系的哪一侧,这提供了双向性。
在这里和那里有一些助手,你有一个提供推荐的智能对象。
另一种更具可扩展性的方法是创建一个仅包含推荐组名称的表,然后创建m2m对象到推荐组,这样你就可以推荐一组foos,查找更容易:foo - > group - >很多泡沫