Easiest way to rename a model using Django/South?
我一直在South的网站google上寻找答案,但找不到一个简单的方法来解决这个问题。
我想用south重命名一个django模型。假设您有以下内容:
1 2 3 4 5 6 | class Foo(models.Model): name = models.CharField() class FooTwo(models.Model): name = models.CharField() foo = models.ForeignKey(Foo) |
你想把foo转换成bar,也就是
1 2 3 4 5 6 | class Bar(models.Model): name = models.CharField() class FooTwo(models.Model): name = models.CharField() foo = models.ForeignKey(Bar) |
号
简单来说,我只是想把名字从
使用South最简单的方法是什么?
要回答第一个问题,简单的模型/表重命名非常简单。运行命令:
1 | ./manage.py schemamigration yourapp rename_foo_to_bar --empty |
(更新2:尝试使用
如果您使用的是较旧版本的South,则需要使用
然后手动编辑迁移文件,如下所示:
1 2 3 4 5 6 7 8 | class Migration(SchemaMigration): def forwards(self, orm): db.rename_table('yourapp_foo', 'yourapp_bar') def backwards(self, orm): db.rename_table('yourapp_bar','yourapp_foo') |
号
您可以在模型类中更简单地使用
(更新)我刚在生产环境中尝试过,在应用迁移时收到了一个奇怪的警告。它说:
1
2
3
4
5
6
7 The following content types are stale and need to be deleted:
yourapp | foo
Any objects related to these content types by a foreign key will also
be deleted. Are you sure you want to delete these content types?
If you're unsure, answer 'no'.
号
我回答"不",一切似乎都很好。
在
1 | ./manage.py schemamigration --auto myapp |
当您检查迁移文件时,您将看到它删除了一个表并创建了一个新的表。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class Migration(SchemaMigration): def forwards(self, orm): # Deleting model 'Foo' db.delete_table('myapp_foo') # Adding model 'Bar' db.create_table('myapp_bar', ( ... )) db.send_create_signal('myapp', ['Bar']) def backwards(self, orm): ... |
。
这不是你想要的。相反,编辑迁移,使其看起来像:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class Migration(SchemaMigration): def forwards(self, orm): # Renaming model from 'Foo' to 'Bar' db.rename_table('myapp_foo', 'myapp_bar') if not db.dry_run: orm['contenttypes.contenttype'].objects.filter( app_label='myapp', model='foo').update(model='bar') def backwards(self, orm): # Renaming model from 'Bar' to 'Foo' db.rename_table('myapp_bar', 'myapp_foo') if not db.dry_run: orm['contenttypes.contenttype'].objects.filter(app_label='myapp', model='bar').update(model='foo') |
在没有
另外,如果您重命名了一些列,这些列是重命名模型的外键,请不要忘记
1 | db.rename_column(myapp_model, foo_id, bar_id) |
。
南方自己做不到——它怎么知道
最后,你真的需要这样做吗?我还需要重新命名模型——模型名称只是一个实现细节——特别是考虑到
我遵循上面利奥波德的解决方案。但是,这并没有改变模型的名称。我在代码中手动更改了它(也在相关模型中,这里称为fk)。做了另一次南方移民,但有——假选择。这使得模型名和表名相同。
刚意识到,可以先更改模型名,然后在应用迁移文件之前编辑它们。更干净。