对于ManyToMany字段使用'through'时如何向南迁移?

时间:2011-10-24 16:12:17

标签: python django django-south

我想在django app中更改ManyToMany字段。

我有以下型号:

class A:
    ...

class B:
    as = models.ManyToManyField(A)

我希望:

class A:
    ...

class C:
     a = models.ForeignKey(A)
     b = models.ForeignKey("B")
     extra_data = models.BooleanField(default=False)

class B:
    as = models.ManyToManyField(A, through=C)

我正在使用南方进行数据库迁移。不幸的是,在这种情况下,南方建议删除现有的app_b_a表并重新创建新的app_c

有没有办法说南方不要重新创建m2m表?

3 个答案:

答案 0 :(得分:6)

我会尝试以下方式:

  1. 添加C模型,但尚未添加任何额外数据字段。只需将2 FK设置为​​链接模型,这样它的模式实际上与默认的m2m表相同,除了表名。
  2. 为您的应用运行schemamigration --auto
  3. 要有效地“删除”现有表并“创建”新表而不移动数据,只需从forwards / backwards方法中删除所有生成的迁移代码,然后添加: 转发: db.rename_table('yourappname_m2mtablename', 'yourappname_c') 向后: db.rename_table('yourappname_c', 'yourappname_m2mtablename')
  4. 保持“冻结”模型dict原样!
  5. 现在,您可以扩展C模型并为其生成新的模式迁移。

答案 1 :(得分:2)

最近我必须自己这样做。这实际上相当容易。

首先,将新的直通模型添加到您的代码中,但将其指定为through的{​​{1}}参数。创建一个自动模式迁移,它将为您创建新表。

ManyToManyField

其次,创建一个数据迁移:

$ python manage.py schemamigration --auto yourapp

在您的转发中:

$ python manage.py datamigration yourapp name_of_migration

在您的向后迁移中:

for b in orm.B.objects.all():
    for a in b.as.all():
        orm.C.objects.create(a=a, b=b)

最后,将for c in orm.C.objects.all(): c.b.as.add(a) 参数添加到through,然后生成另一个自动架构迁移:

ManyToManyField

答案 2 :(得分:0)

您还可以尝试将C的db_table参数指定为“app_b_a”。但不确定那会奏效。