使用Django/South重命名模型的最简单方法是什么?

21 浏览
0 Comments

使用Django/South重命名模型的最简单方法是什么?

我在South的网站、Google和SO上寻找了答案,但找不到一个简单的方法来做到这一点。

我想使用South来重命名一个Django模型。

假设你有以下代码:

class Foo(models.Model):

name = models.CharField()

class FooTwo(models.Model):

name = models.CharField()

foo = models.ForeignKey(Foo)

你想要将Foo转换成Bar,即:

class Bar(models.Model):

name = models.CharField()

class FooTwo(models.Model):

name = models.CharField()

foo = models.ForeignKey(Bar)

为了保持简单,我只是想将名称从Foo更改为Bar,现在先忽略FooTwo中的foo成员。

使用South最简单的方法是什么?

  1. 我可能可以进行数据迁移,但这似乎相当复杂。
  2. 编写一个自定义迁移,例如db.rename_table('city_citystate', 'geo_citystate'),但不确定如何在这种情况下修复外键。
  3. 您知道的更简单的方法?
0
0 Comments

问题的原因是需要将Django模型重命名,但是South不直接支持此功能。解决方法是使用South的迁移功能手动修改迁移文件,将表重命名的操作改为使用db.rename_table()函数。

具体的解决方法如下:

1. 运行以下命令创建一个空的迁移文件:./manage.py schemamigration yourapp rename_foo_to_bar --empty

2. 手动编辑迁移文件,将其内容修改为如下形式:

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')   

3. 最后,运行迁移命令将修改应用到数据库中:./manage.py migrate yourapp

需要注意的是,此方法可能会导致一些潜在问题,比如删除旧表时会提示是否删除关联的对象,如果选择删除,可能会导致数据丢失。另外,此方法也无法重命名表的索引和自动生成的表的列名。

总结起来,虽然这种方法可以实现Django模型的重命名,但是使用South进行模型重命名并不是一种推荐的做法,因为South并不直接支持此功能,而且可能会导致一些潜在问题。因此,在实际项目中,最好避免频繁修改模型名称,以增加代码的可读性和可维护性。

0
0 Comments

在使用Django/South重命名一个模型时,可能会出现以下问题:更改了models.py中的内容后,运行./manage.py schemamigration --auto myapp命令生成的迁移文件中,会删除原来的表并创建一个新的表,而不是进行模型的重命名操作。为了解决这个问题,可以通过编辑迁移文件来实现模型重命名操作。

具体的解决方法如下:首先,在迁移文件的forwards方法中,通过db.rename_table('myapp_foo', 'myapp_bar')命令将数据库中的表名从myapp_foo改为myapp_bar。然后,通过orm['contenttypes.contenttype'].objects.filter(app_label='myapp', model='foo').update(model='bar')命令将ContentType模型中指向原来模型的对象的模型名称更新为新的模型名称。在backwards方法中,通过db.rename_table('myapp_bar', 'myapp_foo')命令将数据库中的表名从myapp_bar改回myapp_foo,并通过orm['contenttypes.contenttype'].objects.filter(app_label='myapp', model='bar').update(model='foo')命令将ContentType模型中指向新模型的对象的模型名称更新为原来的模型名称。

另外,如果重命名的模型有外键指向其他列,也需要使用db.rename_column(myapp_model, foo_id, bar_id)命令将外键列的名称同步更新。

在使用Django 1.6版本时,可能会出现错误信息:KeyError: "The model 'contenttype' from the app 'contenttypes' is not available in this migration.",同时可能会发现没有contenttypes表,而只有django_content_type表。为了解决这个问题,可以通过在单独的数据迁移中更新ContentType模型,并使用--frozen参数将contenttypes.ContentType模型添加到冻结模型中。

具体的解决方法如下:首先,使用./manage.py datamigration --frozen contenttypes myapp update_contenttypes命令创建一个冻结的数据迁移文件,然后在生成的迁移文件中添加上述更新ContentType模型的代码。

以上就是使用Django/South重命名模型时可能出现的问题及解决方法。

0
0 Comments

问题的出现原因:

South无法自己完成这个任务 - 它怎么知道Bar代表了Foo的内容?这是我会为其编写一个自定义迁移的问题。您可以像上面那样在代码中更改ForeignKey,然后只需重命名相应的字段和表即可,可以按照任何方式进行操作。

解决方法:

有必要这样做吗?我还没有需要重命名模型的情况 - 模型名称只是一个实现细节 - 特别是考虑到verbose_name Meta选项的可用性。

或者,在代码中重命名模型,但使用db_table Meta选项来保持数据库表名不变。

- 您是否知道db_table用于推导外键名称?

我相信是的。如果您更改模型名称并设置db_table,则一切应该按预期工作。

这是整个线程中最好的解决方案!

0