代码之家  ›  专栏  ›  技术社区  ›  cezar Dennis Kioko

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

  •  1
  • cezar Dennis Kioko  · 技术社区  · 7 年前

    为了描述我的问题,我们假设有一个模型类 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
    

    一个人可以有许多(或没有)这类亲属:

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

    为了描述关系类型,我们需要另一个模型类和选项 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不能是母亲的同父异母兄弟
    • 实现管理器或查询集以显示个人的子女、父母和兄弟姐妹

    您是否有其他想法如何以干净的方式实现这一点?方法是否具有 亲戚 很好或者我应该把它分成两个不同的领域 parents siblings ?

    除上述关系外,没有其他关系。不能总是根据现有条目确定关系,例如A和B是父系同父异母,但其父母不在数据库中。

    1 回复  |  直到 7 年前
        1
  •  1
  •   bruno desthuilliers    7 年前

    事实上你没有 使用 ManyToManyField 当您使用显式中间模型时,只需省略 曼尼托曼尼菲尔德 在里面 Person (在你的 Relatedness 模型),并在中提供您自己的相关访问器 (使用属性和相关查询集查找)。