我有一个非常相似的情况:Django migration strategy for renaming a model and relationship fields
我需要将 Foo 重命名为 Bar。
我们有一个相同的 myapp:
class Foo(models.Model):
name = models.CharField(unique=True, max_length=32)
description = models.TextField(null=True, blank=True)
但是我的 myotherapp 中有一个 ManyToMany 字段:
class AnotherModel(models.Model):
foo = models.ForeignKey(Foo)
is_awesome = models.BooleanField()
class YetAnotherModel(models.Model):
foo = models.ManyToManyField(Foo, blank=True, null=True) # Here!
is_ridonkulous = models.BooleanField()
我试过重命名:
foo = models.ManyToManyField(Foo, blank=True, null=True)
到 IntegerField() 但不起作用。我该怎么做?
请您参考如下方法:
我是这样做的。注意:我不是在生产中,所以我不必担心表中已有的信息。如果您当前有需要保留在链接表中的数据,请先备份您的数据。此外,我使用的是 Django 1.9,但我认为此处引用的所有内容也在 1.8 中。
多对多关系的问题在于中间表。使用 RemoveField 和 AddField 处理了这个问题。
模型重命名的 myapp 迁移可能看起来像这样:
class Migration(migrations.Migration):
dependencies = [
('Foo', '0001_initial.py'),
]
operations = [
migrations.RenameModel(
old_name='Foo',
new_name='Bar',
),
]
接下来你会运行:
python manage.py makemigrations --empty myotherapp
然后你会把这段代码放在新的迁移中:
dependencies = [
('myotherapp', '0001_initial.py'),
('myapp', '0002_whateverthismigrationwasnamed')
]
operations = [
migrations.RemoveField(
model_name='YetAnotherModel',
name='Foo'
),
migrations.AddField(
model_name='YetAnotherModel',
name='Bar',
field=models.ManyToManyField(blank=True, null=True, to='myapp.Bar'),
),
]
请务必确保将来自 myapp 的重命名模型迁移添加为依赖项,以便它首先运行。
现在,如果您在生产中,您应该不在未采取预防措施的情况下使用此方法。它直接删除链接表。这来自django docs在 RemoveField 上:
Bear in mind that when reversed, this is actually adding a field to a model. The operation is reversible (apart from any data loss, which of course is irreversible) if the field is nullable or if it has a default value that can be used to populate the recreated column.
如果您在生产环境中,您需要采取措施备份数据,以便将其恢复到新表中。
