Django ORM配偶,孩子,父母关系

时间:2014-01-30 22:59:49

标签: django orm foreign-key-relationship relationships

我有一个名为Person的模型,一个人可能有也可能没有几个关系;配偶,孩子,父母。如果该人有配偶,但该配偶不是数据库中的人,我希望能够将配偶保持为字符串值,而不是另一个人。因此我假设我需要在m2m关系中指定through模型:

class Person(models.Model):
    spouse = models.ManyToManyField('self', through='Relationship')
    children = models.ManyToManyField('self', through='Relationship')
    parents = models.ManyToManyField('self', through='Relationship')

class Relationship(models.Model):
    personA = models.ForeignKey(Person)
    personB = models.ForeignKey(Person, blank=True, null=True)
    person_name = models.TextField(default='', blank=True)
    relationship = models.CharField(choices=(('s', 'spouse'),
                                             ('c', 'child'),
                                             ('p', 'parent')),
                                    default='s')

当我尝试运行./manage.py迁移时,我收到以下错误消息:

CommandError: One or more models did not validate:
myapp.person: Many-to-many fields with intermediate tables cannot be symmetrical.
myapp.person: Many-to-many fields with intermediate tables cannot be symmetrical.
myapp.person: The model Person has two manually-defined m2m relations through the model Relationship, which is not permitted. Please consider using an extra field on your intermediary model instead.
myapp.person: Many-to-many fields with intermediate tables cannot be symmetrical.
myapp.person: The model Person has two manually-defined m2m relations through the model Relationship, which is not permitted. Please consider using an extra field on your intermediary model instead.
myapp.relationship: Accessor for field 'personA' clashes with related field 'Person.relationship_set'. Add a related_name argument to the definition for 'personA'.
myapp.relationship: Accessor for field 'personB' clashes with related field 'Person.relationship_set'. Add a related_name argument to the definition for 'personB'.

显然我做错了。

如何指定同一模型与该关系相关的额外数据之间的关系?

或者,您还可以如何构建这些模型以跟踪相同的数据?

1 个答案:

答案 0 :(得分:0)

Error creating several recursive m2m relationships似乎是一个相关的问题。我意识到,通过从parents模型中移除childrenspousePerson字段并将related_name设置为relationships,我可以获得相同的效果Relationship模型。

class Person(models.Model):
    [ other fields ]

class Relationship(models.Model):
    personA = models.ForeignKey(Person, related_name='relationships')
    personB = models.ForeignKey(Person, blank=True, null=True)
    person_name = models.TextField(default='', blank=True)
    relationship = models.CharField(choices=(('s', 'spouse'),
                                             ('c', 'child'),
                                             ('p', 'parent')),
                                    default='s')

我还没有测试过它,但它确实验证并且不再抛出错误消息。这似乎也更清晰。

我想我可以在Person模型上创建一些属性,以便我可以访问Person.spouse,它会返回Person.relationships所有relationship == 's'