Python Django-如何使用South重命名模型字段?

Python Django-如何使用South重命名模型字段?,python,django,django-models,django-south,Python,Django,Django Models,Django South,我想更改模型中特定字段的名称: class Foo(models.Model): name = models.CharField() rel = models.ForeignKey(Bar) 应改为: class Foo(models.Model): full_name = models.CharField() odd_relation = models.ForeignKey(Bar) 使用South最简单的方法是什么?您可以使用该功能 class

我想更改模型中特定字段的名称:

class Foo(models.Model):
    name = models.CharField()
    rel  = models.ForeignKey(Bar)
应改为:

class Foo(models.Model):
    full_name     = models.CharField()
    odd_relation  = models.ForeignKey(Bar)
使用South最简单的方法是什么?

您可以使用该功能

class Migration:

    def forwards(self, orm):
        # Rename 'name' field to 'full_name'
        db.rename_column('app_foo', 'name', 'full_name')




    def backwards(self, orm):
        # Rename 'full_name' field to 'name'
        db.rename_column('app_foo', 'full_name', 'name')
db.rename\u column
的第一个参数是表名,因此记住如何:

Django自动从模型类和包含它的应用程序的名称派生数据库表的名称。模型的数据库表名是通过将模型的“应用程序标签”(manage.py startapp中使用的名称)连接到模型的类名来构造的,它们之间带有下划线


如果您有一个多字、驼峰式的模型名,例如ProjectItem,表名将是
app\u ProjectItem
(即,在
project
item
之间不会插入下划线,即使它们是驼峰式的)。

我不知道db.rename列,听起来很方便,然而,在过去,我将新列添加为一个模式迁移,然后创建一个数据迁移以将值移动到新字段中,然后创建第二个模式迁移以删除旧列

  • 在模型中更改列名(在本例中为
    myapp/models.py
  • 运行
    /manage.py schemamigration myapp renaming\u column\u x--auto
  • 注意
    重命名列\u x
    可以是任何您喜欢的方式,这只是为迁移文件提供描述性名称的一种方式

    这将生成一个名为
    myapp/migrations/000x\u renaming\u column\u x.py
    的文件,该文件将删除旧列并添加新列

    修改此文件中的代码,将迁移行为更改为简单重命名:

    class Migration(SchemaMigration):
    
        def forwards(self, orm):
            # Renaming column 'mymodel.old_column_name' to 'mymodel.new_column_name'
            db.rename_column(u'myapp_mymodel', 'old_column_name', 'new_column_name')
    
        def backwards(self, orm):
            # Renaming column 'mymodel.new_column_name' to 'mymodel.old_column_name'
            db.rename_column(u'myapp_mymodel', 'new_column_name', 'old_column_name')
    
  • south
    添加到项目设置文件中已安装的应用程序中
  • 注释掉添加/修改的字段/表
  • $manage.py模式迁移--初始值
  • $manage.py migrate--false
  • 取消对字段的注释并写入修改后的字段
  • $manage.py模式迁移--自动
  • $manage.py迁移
  • 如果您使用的是“pycharm”,那么您可以使用“ctrl+shift+r”而不是“manage.py”,并使用“shift”作为参数。

    Django 1.7引入,因此现在您甚至不需要安装额外的软件包来管理迁移

    要重命名模型,需要先创建空迁移:

    $ manage.py makemigrations <app_name> --empty
    
    之后,您需要运行:

    $ manage.py migrate <app_name>
    
    $manage.py迁移
    
    只需更改模型并在1.9中运行
    makemigrations

    Django自动检测到您已删除并创建了单个字段,并询问:

    Did you rename model.old to model.new (a IntegerField)? [y/N]
    

    如果说是,就会创建正确的迁移。神奇。

    这对name\full\u name有效,但对relation字段无效,对吗?重要提示:如果要使用此选项,请确保“app\u foo”是数据库表名,例如:“mainapp\u profile”,“name”是数据库的旧列名(而不是模型字段名),例如:“user\u id”和“full\u name”将是您希望列具有的新名称(同样,是数据库列,而不是字段名)。因此:db.rename_column('mainapp_profile'、'user_id'、'new_user_id')同样,如果你处理外键,在重命名时应该在其中包含“_id”部分。如果你手动执行此db.rename_column,你可能需要在之后执行一个伪模式迁移来清理备份。即首先通过重命名列来迁移更改。然后修复模型(更新名称),然后执行./manage.py schemamigration app--auto&&./manage.py migration app--fake)。您还可以使用./manage.py schemamigration my_app renaming_column_x--empty创建空迁移,只需将代码放入其中--empty没有多大帮助,而是使用--auto和modify created migration。这样,它就不会声明字段已为models.py.Me的下一次迁移而被删除。模式数据模式技术的问题在于,字段/模型的名称不同。有时,如果您使用规范名称来启用dispatchers,这是一个问题……我只是尝试了一下,但没有成功,因为存在名称冲突。我有完全相同的FK,但不同的名字。它没有验证。所以,不要这样做。@乔纳森,他想要不同的名字@朝圣者,想贴些密码吗?这周我已经做了好几次了,如果你的模型没有验证,那么south就不会创建迁移。这会起作用,但可能比其他人建议的“重命名列”要慢。我知道MySQL可以很快地执行“更改表…重命名列”(或其他任何操作)。@Rory
    db.rename\u column
    不会为您重命名约束,因此您必须手动处理。如果您忘记这样做,迁移将起作用,除非您不知道可能存在仍然使用旧列名的约束。我不清楚这个问题是否只是表面上的,或者在未来的移民中,限制应该被操纵或放弃,南方是否会找不到它。无论如何,像sjh建议的那样在这里进行操作是安全的方法:您可以让South了解它应该了解的内容。另请参见重命名模型而不是模型字段。您的命令中的列名称是什么
    x
    column\u x
    ?您所指的命令部分仅用于命名迁移,它可以是您喜欢的任何名称。编辑迁移文件时,需要在迁移文件中指定列名。首先创建
    --auto
    迁移是一个很好的技巧。它避免了南部ORM冻结器出现问题,如果迁移只有
    向前
    向后
    方法,但不包含冻结的
    模型
    对象,则会出现这种问题。我如何回答南部的问题“既然要删除此字段,必须指定默认值”?此方法的一个问题是
    Did you rename model.old to model.new (a IntegerField)? [y/N]