Django多对多(m2m)与同一模型的关系

Ron*_*Ron 39 python django many-to-many django-models

我想从用户类对象创建多对多关系.

我有这样的事情:

class MyUser(models.Model):
    ...
    blocked_users = models.ManyToManyField(MyUser, blank=True, null=True)
Run Code Online (Sandbox Code Playgroud)

问题是我是否可以在其内部使用类引用.或者我必须使用"self"插入"MyUser"ManyToManyField?或者还有另一种(更好的)方法吗?

Chr*_*att 64

从技术上讲,我很确定"MyUser"或"self"会起作用,只要它在任何一种情况下都是一个字符串.你只是无法通过MyUser,实际上课.

但是,文档总是使用"自我".使用"self"不仅更明确地了解实际发生的事情,而且它不受类名更改的影响.例如,如果您以后更改MyUserSomethingElse,则需要更新对"MyUser"的任何引用.问题是因为它是一个字符串,你的IDE不会提醒你错误,所以你错过了它的可能性更大.无论现在或未来的班级名称如何,使用"自我"都会有效.

  • @ParaM示例:您希望在其中指定“相关文章”的文章模型 (2认同)

Goi*_*oin 38

class MyUser(models.Model):
    ...
    blocked_users = models.ManyToManyField("self", blank=True)
Run Code Online (Sandbox Code Playgroud)

  • `null = True`对ManyToManyFields没有影响 (6认同)
  • 我没说"MyUser",我说"自我":https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.ManyToManyField.symmetrical (4认同)

小智 6

不要忘记使用对称=假,如果你对相关对象使用 .clear() 或 .add() 方法并且不想在关系另一侧的对象更新关系字段中的自己的数据。

some_field = models.ManyToManyField('self', symmetrical=False)
Run Code Online (Sandbox Code Playgroud)


sah*_*ama 5

我认为它应该是类名而不是自我。因为像这样使用 self

parent = models.ManyToManyField('self', null=True, blank=True)
Run Code Online (Sandbox Code Playgroud)

当我添加父项时:

user1.parent.add(user2)
Run Code Online (Sandbox Code Playgroud)

我在数据库中有 2 条记录,如下所示: 在此处输入图片说明

并使用类名比作这样:

parent = models.ManyToManyField('User', null=True, blank=True)
Run Code Online (Sandbox Code Playgroud)

我在数据库中有一个这样的记录: 在此处输入图片说明

请注意,我使用 uuid 进行 pk,我使用 django 3.1

编辑:作为@神罗,转生在评论解释这个答案,我们必须设置symmetrical为False如果我们使用的自我。记录在Django 文档中:ManyToManyField.symmetrical