为父母与孩子和兄弟姐妹建立m2m关系

时间:2017-12-21 11:49:22

标签: python django django-models many-to-many

为了描述我的问题,让我们假设有一个模型类Person

class Person(models.Model):
    name = models.CharField(max_length=100, unique=True)
    sex = models.CharField(
        max_length=1,
        choices=(
            ('F', 'female'),
            ('M', 'male')
        )
    )
    relatives = models.ManyToManyField('self', blank=True)

    def __str__(self):
        return self.name

一个人可以有很多(或没有)这些类型的亲戚:

  • 父母
  • 儿童
  • 兄弟姐妹
  • halfsiblings(母亲或父亲)

为了描述关系类型,我们需要另一个模型类和选项through,在这种情况下还需要选项symmetrical=False

关系亲子确实是不对称的,但兄弟姐妹的关系是对称的 我正在寻找一种优雅而明确的解决方案,以克服兄弟姐妹真正对称关系与父母与子女不对称关系之间的困境。

调整字段relatives并添加其他模型类结果:

class Person(models.Model):
    # ...
    relatives = models.ManyToManyField(
        'self',
        through='Relatedness',
        symmetrical=False,
        blank=True
    )

class Relatedness(models.Model):
    RELATIONSHIPS = (
        ('PA', 'parent'),
        ('SI', 'sibling'),
        ('MH', 'maternal halfsibling'),
        ('PH', 'paternal halfsibling'),
    )
    source = models.ForeignKey('Person', related_name='source')
    target = models.ForeignKey('Person', related_name='target')
    relationship = models.CharField(max_length=2, choices=RELATIONSHIPS)

    class Meta:
        unique_together = ('source', 'target')

我需要的是:

  • 显示一个人的所有亲属
  • 实现约束,没有奇怪的组合,如果A是B的母亲,C是D的母亲,那么B和D不能是母亲的半兄弟
  • 实现管理员或查询集以向个人展示孩子,父母和兄弟姐妹

您是否有任何其他想法如何以干净的方式实施? relatives的方法是好还是我应该将其拆分为两个不同的字段parentssiblings

除了上述关系之外,没有其他关系。不能总是从现有的条目中确定关系,例如A和B是父亲的半兄弟,但他们的父母不在数据库中。

1 个答案:

答案 0 :(得分:1)

实际上,当您使用显式中间模型时, - ManyToManyField (您在ManyToManyField模型中仍然拥有正确的关系),并在Person中提供您自己的相关访问者(使用属性和相关的查询集查找)。