关于python:迁移重命名模型字段ManyToMany Django 1.8

Migration rename model field ManyToMany Django 1.8

我有一个非常类似的情况:用于重命名模型和关系字段的Django迁移策略

我需要将Foo重命名为Bar

我们有一个相同的myapp

1
2
3
class Foo(models.Model):
    name = models.CharField(unique=True, max_length=32)
    description = models.TextField(null=True, blank=True)

但我在我的江户有许多领域:

1
2
3
4
5
6
7
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()

我尝试重命名:

1
foo = models.ManyToManyField(Foo, blank=True, null=True)

但不起作用。我该怎么做?


我就是这样做的。注意:我不在生产中,所以我不必担心表中已经有了信息。如果您当前有需要保存在链接表中的数据,请首先备份您的数据。另外,我使用的是django 1.9,但我认为这里引用的所有内容也在1.8中。

多对多关系的问题是中间表。使用removefield和addfield处理。

模型重命名的myapp迁移可能如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
class Migration(migrations.Migration):

    dependencies = [
        ('Foo', '0001_initial.py'),
    ]

    operations = [
        migrations.RenameModel(
            old_name='Foo',
            new_name='Bar',
        ),
    ]

接下来您将运行:

1
python manage.py makemigrations --empty myotherapp

然后将此代码放入新的迁移中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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 on 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.

如果您正在生产中,您将希望采取步骤备份数据,以便将其还原到新表中。