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

Rom*_*inD 4 python django django-models python-3.x

我想创建一个model(1),其中多个外键指向同一其他model(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')
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点 ?

我已经知道这样做的丑陋方法:

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')
Run Code Online (Sandbox Code Playgroud)

Wil*_*sem 5

related_names不能是相同的,因为这将引入混淆:该相关的对象通过mother不是(精确地)一样通过相关的对象father

你可以(通过引入例如改变你的造型ManyToManyFieldParent,例如在对父母的性别关系添加额外的数据)。但是这种方法的一个缺点是,现在您不再将关系的基数设置为2:这意味着Child(通过设计)一个罐可以有零个父母,一个父母,两个父母,三个父母或更多。此外,孩子可能有两个母亲,或两个父亲,或两个母亲和三个父亲。因此,它可能导致大量额外的逻辑来防止某些情况。请注意,在某些国家/地区是可能的:在某些国家/地区,可以将额外的人列为“父母”,并且他们具有与父母相同的合法权利和义务。

但是,您可以定义这样的属性来获取children,通过进行查询来获取所有Child的物件,mother或者fatherself

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))
Run Code Online (Sandbox Code Playgroud)

例如,您可以命名相关名称'father_of',并'mother_of'使得您可以查询some_parent.mother_of到取得患儿,其中some_parentmother_of。例如,如果您想列出包含母亲及其子女的表,或者在可能Parent更改性别的情况下进行申请,这可能会很有用。

但是,如果要使用严格的Fathers和Mothers,则定义两个单独的模型可能会有所帮助。优点是您既可以命名related_names 'children',又可以通过设计检查fathera 的s Child是男性(对于mother女性是相似的)。