如何通过模型编写与自己的多对多关系的Django模型

时间:2010-10-07 09:53:28

标签: django django-models django-orm

我希望有一个与自身有ManyToMany关系的模型,我不知道如何编写这个但我会尝试编写一些代码来说明我想要做的事情。

class Person(models.Model):
   name = models.CharField()
   occupation = models.CharField()

   friends = models.ManyToManyField('self', through = PersonFriends)

我的模特,我希望朋友们通过

class PersonFriends(models.Model)
   ???
   comment = models.CharField()

ManyToMany字段中通过关系如果其他模型的名称是“Pet”,例如我会通过类person和{{ 1}}并制作模型。例如petForeignKey(Person)

我在Pet模型中为两个人字段命名我的fields,因为他们是同一个模型?

4 个答案:

答案 0 :(得分:14)

您可以这样做:

class Person(models.Model):
    name = models.CharField(max_length = 255)
    occupation = models.CharField(max_length = 255)
    friends = models.ManyToManyField('self', through = 'PersonFriends', 
          symmetrical = False)
    #     ^^^^^^^^^^^
    # This has to be false when using `through` models. Or else your 
    # model will not validate.

class PersonFriends(models.Model):
    source = models.ForeignKey(Person, related_name = 'source')
    #                                  ^^^^^^^^^^^^
    # You need different `related_name` for each when you have 
    # multiple foreign keys to the same table. 

    target = models.ForeignKey(Person, related_name = 'target')
    comment = models.CharField(max_length = 255)

答案 1 :(得分:2)

不假设友谊是对称的。因为巴斯光年可能是伍迪的朋友,但伍迪并不是巴斯光年的朋友,直到电影结束。您可以简化两种模型,但仍具有合理的查找名称。如果这是一个很好的友谊,你当然需要确保定义两个PersonFriends。

class Person(models.Model):
   name = models.CharField()
   occupation = models.CharField()

class PersonFriends(models.Model):
    from_person = models.ForeignKey(Person, related_name='friends_with')
    to_person = models.ForeignKey(Person, related_name='friends')
    comment = models.CharField()
    class Meta:
        unique_together = ('from_person', 'to_person')

这对友谊的每个方向都有额外的评价。也就是提利昂认为Sansa是一个可爱而聪明但却迷失的女孩。虽然Sansa可能认为提利昂是一个丑陋但聪明善良的人。

答案 2 :(得分:1)

class PersonFriends(models.Model):
    from_person = models.ForeignKey(Person, related_name='from_person')
    to_person = models.ForeignKey(Person, related_name='to_person')

这是来自我的Model结构的ManyToMany与self的db表结构。 Django将其定义为......

答案 3 :(得分:0)

official docs for ManyToManyField.through_fields中描述了所有内容(您可以在那里搜索“递归关系”词组以快速找到所需内容):

对于django 1.11,你必须指定通过和(!)through_fields参数:

class Person(models.Model):
    name = models.CharField(max_length=50)

    # note the additional arguments here
    friends = models.ManyToManyField(
        'self',

        # recursive relationships to self with intermediary
        # through model are always defined as non-symmetrical
        symmetrical=False,

        through='PersonFriend',

        # this argument is required to define a custom
        # through model for many to many relationship to self
        # position matters: 1 - source (from), 2 - target (to)
        through_fields=('person', 'friend'),        
    )


class PersonFriend(models.Model):
    # required relationship-defining foreign keys
    # (note that the order does not matter, it matters
    # in 'through_fields' argument in 'friends' field of the 'Person' model)
    person = models.ForeignKey(Person, on_delete=models.CASCADE)
    friend = models.ForeignKey(Person, on_delete=models.CASCADE)

    # additional fields
    comment = models.CharField()