用于重命名模型和关系字段的 Django 迁移策略 [英] Django migration strategy for renaming a model and relationship fields

查看:25
本文介绍了用于重命名模型和关系字段的 Django 迁移策略的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我计划重命名现有 Django 项目中的多个模型,其中有许多其他模型与我想重命名的模型具有外键关系.我相当肯定这将需要多次迁移,但我不确定确切的过程.

I'm planning to rename several models in an existing Django project where there are many other models that have foreign key relationships to the models I would like to rename. I'm fairly certain this will require multiple migrations, but I'm not sure of the exact procedure.

假设我从名为 myapp 的 Django 应用程序中的以下模型开始:

Let's say I start out with the following models within a Django app called myapp:

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


class AnotherModel(models.Model):
    foo = models.ForeignKey(Foo)
    is_awesome = models.BooleanField()


class YetAnotherModel(models.Model):
    foo = models.ForeignKey(Foo)
    is_ridonkulous = models.BooleanField()

我想重命名 Foo 模型,因为该名称实际上没有意义并且会导致代码混淆,而 Bar 会使名称更加清晰.

I want to rename the Foo model because the name doesn't really make sense and is causing confusion in the code, and Bar would make for a much clearer name.

根据我在 Django 开发文档中阅读的内容,我假设以下迁移策略:

From what I have read in the Django development documentation, I'm assuming the following migration strategy:

修改models.py:

class Bar(models.Model):  # <-- changed model name
    name = models.CharField(unique=True, max_length=32)
    description = models.TextField(null=True, blank=True)


class AnotherModel(models.Model):
    foo = models.ForeignKey(Bar)  # <-- changed relation, but not field name
    is_awesome = models.BooleanField()


class YetAnotherModel(models.Model):
    foo = models.ForeignKey(Bar)  # <-- changed relation, but not field name
    is_ridonkulous = models.BooleanField()

注意 fooAnotherModel 字段名称没有改变,但关系更新为 Bar 模型.我的理由是我不应该一次更改太多,如果我将此字段名称更改为 bar,我可能会丢失该列中的数据.

Note the AnotherModel field name for foo doesn't change, but the relation is updated to the Bar model. My reasoning is that I shouldn't change too much at once and that if I changed this field name to bar I would risk losing the data in that column.

创建一个空的迁移:

python manage.py makemigrations --empty myapp

步骤 3

编辑步骤 2 中创建的迁移文件中的 Migration 类,将 RenameModel 操作添加到操作列表中:

Step 3

Edit the Migration class in the migration file created in step 2 to add the RenameModel operation to the operations list:

class Migration(migrations.Migration):

    dependencies = [
        ('myapp', '0001_initial'),
    ]

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

步骤 4

应用迁移:

python manage.py migrate

步骤 5

编辑models.py中的相关字段名称:

class Bar(models.Model):
    name = models.CharField(unique=True, max_length=32)
    description = models.TextField(null=True, blank=True)


class AnotherModel(models.Model):
    bar = models.ForeignKey(Bar)  # <-- changed field name
    is_awesome = models.BooleanField()


class YetAnotherModel(models.Model):
    bar = models.ForeignKey(Bar)  # <-- changed field name
    is_ridonkulous = models.BooleanField()

步骤 6

创建另一个空迁移:

Step 6

Create another empty migration:

python manage.py makemigrations --empty myapp

步骤 7

编辑在步骤 6 中创建的迁移文件中的 Migration 类,将任何相关字段名称的 RenameField 操作添加到操作列表中:

Step 7

Edit the Migration class in the migration file created in step 6 to add the RenameField operation(s) for any related field names to the operations list:

class Migration(migrations.Migration):

    dependencies = [
        ('myapp', '0002_rename_fields'),  # <-- is this okay?
    ]

    operations = [
        migrations.RenameField('AnotherModel', 'foo', 'bar'),
        migrations.RenameField('YetAnotherModel', 'foo', 'bar')
    ]

步骤 8

应用第二次迁移:

Step 8

Apply the 2nd migration:

python manage.py migrate


除了更新其余代码(视图、表单等)以反映新的变量名称之外,这基本上是新迁移功能的工作方式吗?


Aside from updating the rest of the code (views, forms, etc.) to reflect the new variable names, is this basically how the new migration functionality would work?

此外,这似乎需要很多步骤.能否以某种方式压缩迁移操作?

Also, this seems like a lot of steps. Can the migration operations be condensed in some way?

谢谢!

推荐答案

所以当我尝试这个的时候,你似乎可以压缩步骤 3 - 7:

So when I tried this, it seems you can condense Step 3 - 7:

class Migration(migrations.Migration):

    dependencies = [
        ('myapp', '0001_initial'), 
    ]

    operations = [
        migrations.RenameModel('Foo', 'Bar'),
        migrations.RenameField('AnotherModel', 'foo', 'bar'),
        migrations.RenameField('YetAnotherModel', 'foo', 'bar')
    ]

如果您不更新导入的名称,您可能会遇到一些错误,例如admin.py 甚至更旧的迁移文件 (!).

You may get some errors if you don't update the names where it's imported e.g. admin.py and even older migration files (!).

更新:作为 ceasaro 提到,较新版本的 Django 通常能够检测并询问模型是否已重命名.所以先试试 manage.py makemigrations 再检查迁移文件.

Update: As ceasaro mentions, newer versions of Django are usually able to detect and ask if a model is renamed. So try manage.py makemigrations first and then check the migration file.

这篇关于用于重命名模型和关系字段的 Django 迁移策略的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆