Django Many-to-Many (m2m) Relation to same model

后端 未结 5 805
别跟我提以往
别跟我提以往 2020-12-05 04:17

I\'d like to create a many-to-many relationship from and to a user class object.

I have something like this:

class MyUser(models.Model):
    ...
             


        
相关标签:
5条回答
  • 2020-12-05 04:39

    I think it should be class name instead of self. because with using self like this

    parent = models.ManyToManyField('self', null=True, blank=True)
    

    when i add parent:

    user1.parent.add(user2)
    

    i have 2 record in database like this:

    and with using class name liken this:

    parent = models.ManyToManyField('User', null=True, blank=True)
    

    i have one record in database like this:

    note that i use uuid for pk and i use django 3.1

    EDIT: as @shinra-tensei explained as comment in this answer we have to set symmetrical to False if we use self. documented in Django Documents: ManyToManyField.symmetrical

    0 讨论(0)
  • 2020-12-05 04:41

    If you use self or MyUser you will get a NameError in both cases. You should write "self" as string. See the example below:

    class MyUser(models.Model):
        ...
        blocked_users = models.ManyToManyField("self", blank=True, null=True)
    

    And do not forget to set the symmetrical attribute to False if the relationship is not symmetrical.

    For further details check: https://docs.djangoproject.com/en/3.0/ref/models/fields/#django.db.models.ManyToManyField

    0 讨论(0)
  • 2020-12-05 04:46

    Technically, I'm pretty sure "MyUser" or "self" will work, as long as it's a string in either case. You just can't pass MyUser, the actual class.

    However, the docs always use "self". Using "self" is not only more explicit about what's actually happening, but it's impervious to class name changes. For example, if you later changed MyUser to SomethingElse, you would then need to update any reference to "MyUser" as well. The problem is that since it's a string, your IDE will not alert you to the error, so there's a greater chance of your missing it. Using "self" will work no matter what the class' name is now or in the future.

    0 讨论(0)
  • 2020-12-05 04:56
    class MyUser(models.Model):
        ...
        blocked_users = models.ManyToManyField("self", blank=True)
    
    0 讨论(0)
  • 2020-12-05 04:59

    don't use 'self' in ManyToManyField, it will cause you object link each other, when use django form to submit it

    class Tag(models.Model):
        ...
        subTag = models.ManyToManyField("self", blank=True)
    
     ...
     aTagForm.save()
    

    and result:

     a.subTag == b
     b.subTag == a
    
    0 讨论(0)
提交回复
热议问题