【问题标题】:How do I tell Django to not create a table for an M2M related field?如何告诉 Django 不要为 M2M 相关字段创建表?
【发布时间】:2011-02-05 16:03:02
【问题描述】:

我正在使用这个 Django 代码 sn-p 的小宝石从两个方向编辑 ManyToManyField:

class ManyToManyField_NoSyncdb(models.ManyToManyField):  
    def __init__(self, *args, **kwargs):  
        super(ManyToManyField_NoSyncdb, self).__init__(*args, **kwargs)
        self.creates_table = False  

class Job(models.Model):  
    persons = ManyToManyField_NoSyncdb( Person, blank=True, db_table='person_jobs' )

(sn-p 详情here)

它让我可以从工作表格中选择给定工作中的所有人员,反之则让我从人员表格中选择一个人的所有工作,并在这两种情况下更新单个 jobs_persons 表。

然而,从 Django 1.0 迁移到 1.2 后,syncdb 现在会生成重复表错误,因为 create_table 显然不再是基类中受支持的属性。

是否有另一种方法来指示 Django 1.2 不要为相关字段创建表?

【问题讨论】:

    标签: django manytomanyfield


    【解决方案1】:

    模型的“托管”元选项可能会有所帮助。来自http://docs.djangoproject.com/en/1.2/ref/models/options/#managed

    如果 managed=False 的模型包含 指向的 ManyToManyField 另一个非托管模型,然后 中间表 多对多连接也不会 创建的。然而,中介 一个托管和一个之间的表 将创建非托管模型。

    如果您需要更改此默认值 行为,创造中介 表作为显式模型(与 根据需要托管集)并使用 ManyToManyField.through 属性 使关系使用您的自定义 型号。

    【讨论】:

      【解决方案2】:

      所以,如果您想在 Admin 中访问两个模型中的 ManyToMany,目前官方 的解决方案是使用inlinemodel 作为第二个模型。几天前我也遇到了同样的问题/需要。而且我对 inlinemodel 解决方案不是很满意(如果您有很多条目,数据库查询会很繁重,不能使用 filter_horizontal 小部件等)。

      我找到的解决方案(适用于 Django 1.2+ 和 syncdb)是这样的:

      class User(models.Model):
          groups = models.ManyToManyField('Group', through='UserGroups')
      
      class Group(models.Model):
          users = models.ManyToManyField('User', through='UserGroups')
      
      class UserGroups(models.Model):
          user_id = models.ForeignKey(User)
          group_id = models.ForeignKey(Group)
      
          class Meta:
              db_table = 'app_user_group'
              auto_created = User
      

      更多信息请见票897

      很遗憾,如果您使用的是 South,则必须在自动创建的每个迁移文件中删除 app_user_group 表的创建。

      【讨论】:

      • 嗯。我在 Django 1.3.1 上,我按照您的示例进行操作(除了我的模型位于不同的模块中,但我认为这无关紧要)。无论如何,当我执行 userObj.groups 之类的操作时,我收到一个错误,其中 Django 显然试图将“用户”用作字符串,而不是弄清楚它是一个对象。有任何想法吗?谢谢。
      • 没有看到你的代码,我不知道。通常它应该可以工作(它仍然在 Django 1.3 中为我工作,没有测试 1.3.1)。问题可能是您的模型位于不同的模块中(当它是一个字符串时,我记不清模型解析是如何工作的)。你检查票#897了吗?有 2 个较新的解决方案。最后一个和我做的一样,但是非常干净和简单。
      【解决方案3】:

      让我把 new solution 贴在 Django 的票 #897 中,Etienne 也提到了。它在 Django 1.2 中运行良好。

      class Test1(models.Model):
          tests2 = models.ManyToManyField('Test2', blank=True)
      
      class Test2(models.Model):
          tests1 = models.ManyToManyField(Test1, through=Test1.tests2.through, blank=True)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-10-22
        • 1970-01-01
        • 2014-12-21
        • 1970-01-01
        • 2011-07-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多