我计划在一个已有的Django项目中重命名几个模型,其中有许多与我想重命名的模型有外键关系的模型。我相当肯定这将需要多次迁移,但我不确定确切的步骤。
假设我从名为myapp的Django应用程序中的以下模型开始
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将使名称更加清晰。
根据我在Django开发文档中所读到的,我假设以下迁移策略:
第一步
修改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()注意,AnotherModel字段名foo没有变化,但关系被更新为Bar模型。我的理由是,我不应该立刻更改太多,如果我将这个字段名更改为bar,我将有可能丢失该列中的数据。
第二步
创建一个空迁移:
python manage.py makemigrations --empty myapp第三步
编辑步骤2中创建的迁移文件中的Migration类,将RenameModel操作添加到操作列表中:
class Migration(migrations.Migration):
dependencies = [
('myapp', '0001_initial'),
]
operations = [
migrations.RenameModel('Foo', 'Bar')
]第四步
应用迁移:
python manage.py migrate第五步
在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()第六步
创建另一个空迁移:
python manage.py makemigrations --empty myapp第7步
在步骤6中创建的迁移文件中编辑Migration类,以便将任何相关字段名的RenameField操作添加到操作列表中:
class Migration(migrations.Migration):
dependencies = [
('myapp', '0002_rename_fields'), # <-- is this okay?
]
operations = [
migrations.RenameField('AnotherModel', 'foo', 'bar'),
migrations.RenameField('YetAnotherModel', 'foo', 'bar')
]步骤8
适用第二次迁移:
python manage.py migrate除了更新代码的其余部分(视图、表单等)为了反映新的变量名,新的迁移功能基本上是这样工作的吗?
而且,这似乎是很多步骤。迁移操作能在某种程度上压缩吗?
谢谢!
发布于 2014-10-07 17:22:03
因此,当我尝试这个时,似乎可以压缩步骤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和更旧的迁移文件(!),可能会出现一些错误。
更新:正如杜巴罗提到的,较新版本的杜巴罗通常能够检测并询问模型是否被重命名。所以,首先尝试manage.py makemigrations,然后检查迁移文件。
发布于 2015-06-03 13:21:19
起初,我认为Fiver的方法适用于我,因为在第4步之前迁移很好。但是,将'ForeignKeyField(Foo)‘隐式更改为'ForeignKeyField(Bar)’在任何迁移中都没有关联。这就是为什么当我想重命名关系字段时迁移失败的原因(步骤5-8)。这可能是因为我的“AnotherModel”和“YetAnotherModel”在其他应用程序中被分派给我。
因此,我按照以下步骤重命名了我的模型和关系字段:
我采用了这的方法,特别是奥特兰策的技巧。
就像我们在,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()步骤1:
将每个OneToOneField(Foo)或ForeignKeyField(Foo)转换为IntegerField()。(这将将关联Foo对象的id保留为整数字段的值)。
class AnotherModel(models.Model):
foo = models.IntegerField()
is_awesome = models.BooleanField()
class YetAnotherModel(models.Model):
foo = models.IntegerField()
is_ridonkulous = models.BooleanField()然后
python manage.py makemigrations
python manage.py migrate步骤2:(类似于Fiver的第2-4步)
更改模型名称
class Bar(models.Model): # <-- changed model name
name = models.CharField(unique=True, max_length=32)
description = models.TextField(null=True, blank=True)创建一个空迁移:
python manage.py makemigrations --empty myapp然后编辑如下:
class Migration(migrations.Migration):
dependencies = [
('myapp', '0001_initial'),
]
operations = [
migrations.RenameModel('Foo', 'Bar')
]最终
python manage.py migrate步骤3:
将IntegerField()转换回以前的ForeignKeyField或OneToOneField,但使用新的条形模型。(前一个整域正在存储id,因此django理解这一点,并重新建立连接,这是很酷的。)
class AnotherModel(models.Model):
foo = models.ForeignKey(Bar)
is_awesome = models.BooleanField()
class YetAnotherModel(models.Model):
foo = models.ForeignKey(Bar)
is_ridonkulous = models.BooleanField()那就做:
python manage.py makemigrations 非常重要,在这一步中,您必须修改每个新迁移并添加对RenameModel Foo-> Bar迁移的依赖项。因此,如果AnotherModel和YetAnotherModel都在肌治疗中,则肌治疗中创建的迁移必须如下所示:
class Migration(migrations.Migration):
dependencies = [
('myapp', '00XX_the_migration_of_myapp_with_renamemodel_foo_bar'),
('myotherapp', '00xx_the_migration_of_myotherapp_with_integerfield'),
]
operations = [
migrations.AlterField(
model_name='anothermodel',
name='foo',
field=models.ForeignKey(to='myapp.Bar'),
),
migrations.AlterField(
model_name='yetanothermodel',
name='foo',
field=models.ForeignKey(to='myapp.Bar')
),
]然后
python manage.py migrate步骤4:
最终您可以重命名您的字段。
class AnotherModel(models.Model):
bar = models.ForeignKey(Bar) <------- Renamed fields
is_awesome = models.BooleanField()
class YetAnotherModel(models.Model):
bar = models.ForeignKey(Bar) <------- Renamed fields
is_ridonkulous = models.BooleanField()然后进行自动重命名
python manage.py makemigrations(django应该问您是否真的重命名了模型名,请说是)
python manage.py migrate就这样!
这适用于Django1.8
发布于 2020-12-10 15:09:20
在当前版本的Django中,您可以重命名模型并运行python manage.py makemigrations,然后django将询问您是否要重命名模型,如果您选择是,那么所有重命名过程都将自动完成。
https://stackoverflow.com/questions/25091130
复制相似问题