我想创建一个模型(1),其中多个外键指向同一其他模型(2)。
我希望这些外键具有相同的related_name
,因为每个外键都将指向model(2)的不同实例,因为所有外键都需要一个反向关系。
也许一个例子会更明确:
class Parent(Model):
name = models.CharField(max_length=100)
class Child(Model):
name = models.CharField(max_length=100)
father = models.ForeignKey(Parent, related_name='children')
mother = models.ForeignKey(Parent, related_name='children')
我该怎么做?
我已经知道这样做的丑陋方法:
class Parent(Model):
name = models.CharField(max_length=100)
@property
def children(self):
# Pick the existing one in fields 'children_1' or 'children_2'
class Child(Model):
name = models.CharField(max_length=100)
father = models.ForeignKey(Parent, related_name='children_1')
mother = models.ForeignKey(Parent, related_name='children_2')
答案 0 :(得分:5)
related_names
不能相同,因为这会引起混乱:通过 与mother
相关的对象与对象完全不同。通过father
相关。
您可以更改建模(例如,通过在ManyToManyField
中引入Parent
,例如在有关父母性别的关系中添加额外的数据)。但是这种方法的一个缺点是,现在您不再将关系的基数设置为2:这意味着Child
可以(通过设计)拥有零个父母,一个父母,两个父母,三个父母或更多。此外,孩子可能有两个母亲,或两个父亲,或两个母亲和三个父亲。因此,它可能导致大量额外的逻辑来防止某些情况。请注意,在某些国家/地区是可能的:在某些国家/地区,可以将额外的人列为“父母”,他们与父母具有相同的合法权利和义务。
不过,您可以通过查询获取children
或Child
为{{1的所有mother
对象的查询来定义此类属性以获得father
}}:
self
例如,您可以命名相关名称from django.db.models import Q
class Parent(Model):
name = models.CharField(max_length=100)
@property
def children(self):
return Child.objects.filter(Q(mother=self) | Q(father=self))
和'father_of'
,以便您可以查询'mother_of'
来获得some_parent.mother_of
是some_parent
的孩子。例如,如果您想列出一个有母亲及其子女的表,或者如果您有可能mother_of
改变性别的情况下进行申请,这可能很有用。
但是,如果您想使用严格的Parent
和Father
,则定义两个分离模型可能会有所帮助。优点是您可以同时命名Mother
related_name
,然后根据设计检查'children'
的{{1}}是否为男性(与father
为女性相似)。