如何通过模型编写与SelfToMany关系的Django模型

Joe*_*tar 11 django django-models django-orm

我想要一个ManyToMany与自己有关系的模型,我不知道怎么写这个,但我试着写一些代码来说明我想做什么.

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

   friends = models.ManyToManyField('self', through = PersonFriends)
Run Code Online (Sandbox Code Playgroud)

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

class PersonFriends(models.Model)
   ???
   comment = models.CharField()
Run Code Online (Sandbox Code Playgroud)

ManyToMany与现场通过关系,如果其他模型的名字是"宠物",例如我会通过类的名字我在这领域personpet,使他们的模型.ForeignKey(Person)Pet例如

由于他们是同一个型号,我fields在我的PersonFriends模型中为两个人的名字命名了什么?

Man*_*dan 15

你可以这样做:

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


Bob*_*Bob 5

ManyToManyField.through_fields 的官方文档中描述了所有内容(您可以在那里搜索“递归关系”短语以快速找到您需要的内容):

对于 django 1.11,您必须指定 through 和 (!) 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()
Run Code Online (Sandbox Code Playgroud)