我有一个类似的情况:Django迁移策略,用于重命名模型和关系字段
我需要将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)
到CCD_ 5,但不起作用。我该怎么做?
我就是这样做的。注意:我在生产中是NOT,所以我不必担心表中已经存在的信息。如果您当前有需要保存在链接表中的数据,请首先备份数据。此外,我使用的是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的重命名模型迁移添加为依赖项,以便它首先运行。
现在,如果您正在生产中,您应该NOT在不采取预防措施的情况下使用此方法。它会直接删除链接表。这来自RemoveField:上的django文档
请记住,当反转时,这实际上是在向模型添加字段。如果字段可以为null或具有可用于填充重新创建的列的默认值,则操作是可逆的(除了任何数据丢失,这当然是不可逆的)。
如果您在生产中,则需要采取步骤备份数据,以便将其恢复到新表中。