[英]Django - Symmetrical ForeignKeys or cascade deletion in ManyToMany?
I had a model that looked something like this: 我有一个看起来像这样的模型:
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')
The problem was that foo1
and foo2
need to have the same behavior when they are inverted. 问题在于,当foo1
和foo2
反转时,它们必须具有相同的行为。 In other words, it's something like: "If you liked foo1 you may want to check foo2 out", which should apply the other way around ("If you liked foo2 you may want to check foo1 out"). 换句话说,它类似于:“如果您喜欢foo1,则可能要签出foo2”,这应该采用相反的方式(“如果您喜欢foo2,则可能要签出foo1”)。
So I used a ManyToMany field instead of ForeignKey to make them symmetrical: 所以我使用ManyToMany字段而不是ForeignKey使它们对称:
class Bar(models.Model):
foos = models.ManyToManyField(Foo)
Using a signal to make sure there are never more than 2 foos
: 使用信号确保不超过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)
However, this creates another problem, which is in case a Foo
in foos
is deleted, the Bar
just stays there, but it should be deleted as well (which is solved by cascade deletion in ForeignKeys). 但是,这会带来另一个问题,如果foos
的Foo
被删除, Bar
停foos
,但是也应该将其删除(这通过ForeignKeys中的级联删除来解决)。
How can I solve this? 我该如何解决? Can I make ForeignKeys symmetrical? 我可以使外键对称吗? Or implement cascade deletion in ManyToMany? 还是在ManyToMany中实现级联删除? Or is there another way to solve this? 还是有解决此问题的另一种方法?
I have done this before, the easiest way is to create a pseudo constructor for the model instance that makes sure that item 1 and item 2 are always in order (I used alphabetical but you might as well use id) which makes your uniqueness work ootb. 我之前已经做过,最简单的方法是为模型实例创建一个伪构造函数,以确保第1项和第2项始终按顺序排列(我使用字母顺序,但您也可以使用id),这使您的唯一性起作用。
In the lookups you just look for your item in foo1 or foo2 since you dont mind in which side of the relation it is, which provides the bidirectionality. 在查找中,您只需要在foo1或foo2中查找项目,因为您不介意关系的哪一边,它提供了双向性。
With a few helpers here and there you have a smart object that provides recommendations. 在这里和那里有一些帮助者,您将拥有一个提供建议的智能对象。
Another more extensible approach is to create a table containing only names for recommendation groups and then m2m objects to recommendation groups so you have a group of foos to recommend, the lookup is easier: foo ->group -> many foos 另一个更可扩展的方法是创建一个仅包含推荐组名称的表,然后创建指向推荐组的m2m对象,因此您可以推荐一组foos,查找起来更容易:foo-> group-> many foos
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.