【问题标题】:Django Many-to-Many (m2m) Relation to same modelDjango多对多(m2m)与同一模型的关系
【发布时间】:2012-07-28 02:25:09
【问题描述】:

我想在用户类对象之间创建多对多关系。

我有这样的事情:

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

问题是我是否可以在其内部使用类引用。或者我是否必须在ManyToManyField 中使用"self" 而不是"MyUser"?或者还有其他(更好的)方法吗?

【问题讨论】:

  • 在同一个模型上定义多对多有什么用??任何人请
  • @ParaM 例如,如果你有一个树状结构。主产品有子产品等。
  • “在同一模型上定义多对多有什么用?” 允许每个用户拥有自己的已阻止(或关注)的其他用户列表。
  • 最佳用例是模型的树形结构。

标签: python django django-models many-to-many


【解决方案1】:

从技术上讲,我很确定“MyUser”或“self”会起作用,只要它在任何一种情况下都是字符串。你只是不能通过MyUser,实际的课程。

但是,文档总是使用“self”。使用“self”不仅更明确地说明实际发生的事情,而且不受类名更改的影响。例如,如果您后来将MyUser 更改为SomethingElse,那么您还需要更新对“MyUser”的任何引用。问题是因为它是一个字符串,你的 IDE 不会提醒你错误,所以你错过它的可能性更大。无论现在或将来类的名称是什么,都可以使用“self”。

【讨论】:

  • 在同一模型上定义多对多有什么用??任何人请
  • @ParaM 一个例子:您希望指定“相关文章”的文章模型
  • 一个个人示例是一个代理,其字段指定招募他们的代理。
【解决方案2】:
class MyUser(models.Model):
    ...
    blocked_users = models.ManyToManyField("self", blank=True)

【讨论】:

【解决方案3】:

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

some_field = models.ManyToManyField('self', symmetrical=False)

【讨论】:

    【解决方案4】:

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

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

    当我添加父母时:

    user1.parent.add(user2)
    

    我在数据库中有 2 条记录,如下所示:

    使用类名如下:

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

    我在数据库中有一条这样的记录:

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

    编辑: 正如@shinra-tensei 在this answer 中的评论所解释的那样,如果我们使用self,我们必须将symmetrical 设置为False。记录在Django Documents: ManyToManyField.symmetrical

    【讨论】:

    • 您使用的是什么数据库适配器?那里可能是一个错误......
    • @Ron postgres 和 mysql 都
    【解决方案5】:

    如果您使用 self 或 MyUser 在这两种情况下都会收到 NameError。您应该将 "self" 写为字符串。请看下面的例子:

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

    如果关系不对称,不要忘记将 symmetrical 属性设置为 False。

    更多详情请查看:https://docs.djangoproject.com/en/3.0/ref/models/fields/#django.db.models.ManyToManyField

    【讨论】:

      【解决方案6】:

      在ManyToManyField中不要使用'self',当使用django表单提交时会导致你的对象相互链接

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

      结果:

       a.subTag == b
       b.subTag == a
      

      【讨论】:

      • 有什么建议吗?我从来没有遇到过问题。
      • 我在我的演示中发现了它,最后我使用 ManyToManyField("Tag", blank=True) 来修复它
      • 如果您不希望对象相互链接,请在创建字段 docs.djangoproject.com/en/2.2/ref/models/fields/… 时使用参数 symmetrical = False ,它的存在允许您使用 'self' 名称而不是型号名称
      猜你喜欢
      • 2011-11-15
      • 2012-12-04
      • 2014-05-16
      • 1970-01-01
      • 2019-05-09
      • 1970-01-01
      • 2010-10-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多