【问题标题】:The model has two many-to-many relations through the intermediate model模型通过中间模型有两个多对多关系
【发布时间】:2020-03-06 17:36:11
【问题描述】:

我有一个模型,它有 2 个独立的 ManyToManyField 关系返回到自身

class Company(models.Model):
    parent          =     models.ManyToManyField("self", through='CompanyParent', through_fields=('company_child', 'company_parent'), related_name='+')
    child           =     models.ManyToManyField("self", through='CompanyParent', through_fields=('company_parent', 'company_child'), related_name='+')

以上在我的本地主机 Django v3.0.2/SQLite 3.8.7.2 上运行良好

要真正发布它,我不得不使用 Django v2.1.15/SQLite 3.7.17,但是发布的版本会抛出以下错误

companies.Company.child: (fields.E332) 多对多字段 中间表不能对称。

companies.Company.parent: (fields.E332) 多对多字段 中间表不能对称。

companies.Company: (models.E003) 该模型有两个多对多 通过中间模型 'companies.CompanyParent' 建立关系。

这里发生了什么?通过在每个模型中添加symmetrical=False 解决了前两个问题,但不知道如何解决最终错误?

【问题讨论】:

    标签: python django sqlite


    【解决方案1】:

    您可以检查this answer 来设置两个多对多关系。

    上述答案的一个例子:

    class Person(models.Model): 
        name = models.CharField(max_length=127, blank=False)
        to_users = models.ManyToManyField(
            'self', 
            symmetrical=False, 
            related_name='from_users',
            through='Event', 
            through_fields=('from_user', 'to_user'),
        )
    
    class Event(models.Model):
        item = models.ForeignKey(Item, related_name='events')
        from_user = models.ForeignKey(Person, related_name='events_as_giver')
        to_user = models.ForeignKey(Person, related_name='events_as_receiver')
    

    【讨论】:

    • 我确实看到了;我认为会有更好的方法不需要我更改应用程序的其余部分 - 这很烦人,因为它需要进行一些更改。似乎没有必要 - 为什么它不能在较旧的 Django 版本上运行?
    • 他们已经修复了 this changelogthis PR 的 ManyToMany 字段中的同名问题。因此,从 Django 2.2a1 开始,它允许具有相同的名称。
    【解决方案2】:

    如果有人遇到同样的问题;以上是答案,但我认为在对自己的项目进行必要的更改后会稍微扩展

    如果您希望在同一模型中有许多多对多,并且如果您使用的是 2.2a1 之后的 Django 版本,那么最好的方法是我的问题中详述的方法;两种不同的模型,您可以轻松地在视图或模板上调用它们;例如 -

    > data.manytomany1
    > data.manytomany2
    

    但是,在 2.2a1 之前,您会遇到问题。对我来说,这是因为在 cPanel 上,由于使用了较旧的 SQLite 3.7.17,我必须使用 Django v2.1.15。这意味着您只能拥有一个 ManyToManyField(见上文)并使用过滤器来获取您的第二个 manytomany > 您只能在 views.py 中执行此操作

    希望这是有道理的

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-11
      • 1970-01-01
      • 1970-01-01
      • 2022-01-21
      • 1970-01-01
      • 2019-12-22
      • 1970-01-01
      相关资源
      最近更新 更多