简体   繁体   English

Django多个外键,相同的相关名称

[英]Django multiple foreign key, Same related name

I would like to create a model(1) with multiple foreign keys to the same other model(2). 我想创建一个带有多个外键的模型(1)到同一个其他模型(2)。 I want these foreign keys to have the same related_name because each foreign key will point to difference instances of model(2), because I need one reversed relation for all foreign keys. 我希望这些外键具有相同的related_name因为每个外键将指向model(2)的差异实例,因为我需要一个所有外键的反向关系。

Maybe an example will be more explicit : 也许一个例子会更明确:

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')

How can I do that ? 我怎样才能做到这一点 ?

I already know an ugly way to do so : 我已经知道一种丑陋的方式:

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')

The related_names can not be the same, since this would introduce confusion: an object that is related through the mother is not (exactly) the same as an object related through the father . related_names不能相同,因为这会引起混淆: 通过 mother相关的对象与通过father相关的对象不完全相同。

You can alter your modeling (for example by introducing a ManyToManyField with the Parent , and for example add extra data in the relation about the sex of the parent). 您可以更改建模(例如,通过向Parent引入ManyToManyField ,例如在Parent关系的性别关系中添加额外数据)。 But a disavantage of this approach is that now, you no longer set the cardinality of the relation to 2: it means a Child can (by desing) have zero parents, one parent, two parents, three parents, or more. 但是这种方法的一个缺点是,现在,你不再将关系的基数设置为2:这意味着一个Child可以(通过设计)拥有零父母,一个父母,两个父母,三个父母或更多。 Furthermore it could be possible that a child has two mothers, or two fathers, or two mothers and three fathers. 此外,孩子可能有两个母亲,或两个父亲,或两个母亲和三个父亲。 So it can result in a lot of extra logic to prevent certain cases. 因此,它可以导致许多额外的逻辑来防止某些情况。 Note that in some countries that is possible: in some countries extra people can be listed as "parents", and they have the same legal rights and duties as a parent. 请注意,在某些可能的国家/地区:在某些国家/地区可以将额外的人员列为“父母”,并且他们与父母具有相同的法律权利和义务。

You can however define such property to obtain the children , by making a query to fetch all Child objects where the mother , or the father is self : 但是,您可以通过查询来获取motherfatherself所有Child对象来定义此类属性以获取children

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))

You could for example name the related names 'father_of' and 'mother_of' such that you can query some_parent.mother_of to obtain children where the some_parent is the mother_of . 例如,您可以将相关名称命名为'father_of''mother_of' ,以便查询some_parent.mother_of以获取some_parentmother_of This could be useful if you for example would want to list a table with mothers and their children, or if you would make an application where it is possible that Parent s change gender. 例如,如果您想要与母亲及其子女一起列出表格,或者您可以在Parent改变性别的情况下提出申请,这可能会很有用。

If you however want to have strict Father s and Mother s, then it might be beneficial to define two separate models. 如果你想拥有严格的FatherMother ,那么定义两个独立的模型可能是有益的。 The advantage is that you can both name the related_name s 'children' then, and furthermore by design you check that the father of a Child is a male (and similar for a mother being female). 其优点是,你既可以命名related_name小号'children'然后,进而通过设计 ,你检查的father一的Child是男性(以及类似的mother是女性)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM