问题: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进行此操作最简单的方法是什么?

I would like to change a name of specific fields in a model:

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

should change to:

class Foo(models.Model):
    full_name     = models.CharField()
    odd_relation  = models.ForeignKey(Bar)

What’s the easiest way to do this using South?


回答 0

您可以使用该db.rename_column功能。

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_column是表名,因此记住Django如何创建表名很重要:

Django会自动从您的模型类的名称和包含该表的应用程序中获取数据库表的名称。通过将模型的“应用程序标签”(即您在manage.py startapp中使用的名称)连接到模型的类名称,并在其之间加下划线,来构造模型的数据库表名称。

在你有一个多措辞,骆驼套管型号名称的情况下,如项目项,表名会app_projectitem(即下划线不会之间插入projectitem即使它们是骆驼式大小写)。

You can use the db.rename_column function.

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

The first argument of db.rename_column is the table name, so it’s important to remember how Django creates table names:

Django automatically derives the name of the database table from the name of your model class and the app that contains it. A model’s database table name is constructed by joining the model’s “app label” — the name you used in manage.py startapp — to the model’s class name, with an underscore between them.

In the case where you have a multi-worded, camel-cased model name, such as ProjectItem, the table name will be app_projectitem (i.e., an underscore will not be inserted between project and item even though they are camel-cased).


回答 1

这是我的工作:

  1. 在模型中更改列名(在本示例中为myapp/models.py
  2. ./manage.py schemamigration myapp renaming_column_x --auto

注意renaming_column_x可以是任何您喜欢的东西,它只是给迁移文件起一个描述性名称的一种方式。

这将为您生成一个名为的文件myapp/migrations/000x_renaming_column_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')

Here’s what I do:

  1. Make the column name change in your model (in this example it would be myapp/models.py)
  2. Run ./manage.py schemamigration myapp renaming_column_x --auto

Note renaming_column_x can be anything you like, it’s just a way of giving a descriptive name to the migration file.

This will generate you a file called myapp/migrations/000x_renaming_column_x.py which will delete your old column and add a new column.

Modify the code in this file to change the migration behaviour to a simple rename:

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

回答 2

我不知道db.rename列,听起来很方便,但是在过去,我将新列添加为一个schemamigration,然后创建了一个datamigration将值移到新字段中,然后创建了另一个schemamigration以删除旧列。

I didn’t know about db.rename column, sounds handy, however in the past I have added the new column as one schemamigration, then created a datamigration to move values into the new field, then a second schemamigration to remove the old column


回答 3

Django 1.7引入了Migrations,所以现在您甚至不需要安装额外的软件包即可管理迁移。

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

$ manage.py makemigrations <app_name> --empty

然后,您需要像这样编辑迁移代码:

from django.db import models, migrations

class Migration(migrations.Migration):

dependencies = [
    ('yourapp', 'XXXX_your_previous_migration'),
]

operations = [
    migrations.RenameField(
        model_name='Foo',
        old_name='name',
        new_name='full_name'
    ),
    migrations.RenameField(
        model_name='Foo',
        old_name='rel',
        new_name='odd_relation'
    ),
]

然后,您需要运行:

$ manage.py migrate <app_name>

Django 1.7 introduced Migrations so now you don’t even need to install extra package to manage your migrations.

To rename your model you need to create empty migration first:

$ manage.py makemigrations <app_name> --empty

Then you need to edit your migration’s code like this:

from django.db import models, migrations

class Migration(migrations.Migration):

dependencies = [
    ('yourapp', 'XXXX_your_previous_migration'),
]

operations = [
    migrations.RenameField(
        model_name='Foo',
        old_name='name',
        new_name='full_name'
    ),
    migrations.RenameField(
        model_name='Foo',
        old_name='rel',
        new_name='odd_relation'
    ),
]

And after that you need to run:

$ manage.py migrate <app_name>

回答 4

只需更改模型并makemigrations在1.9中运行

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

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

同意,就可以创建正确的迁移。魔法。

Just change the model and run makemigrations in 1.9

Django automatically detects that you’ve deleted and created a single field, and asks:

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

Say yes, and the right migration gets created. Magic.


回答 5

  1. south在项目设置文件中添加到已安装的应用程序。
  2. 注释掉添加/修改的字段/表。
  3. $ manage.py Schemamigration <app_name> --initial
  4. $ manage.py migrate <app_name> --Fake
  5. 取消注释该字段并写入修改后的字段
  6. $ manage.py Schemamigration --auto
  7. $ manage.py migrate <app_name>

如果使用的是“ pycharm”,则可以使用“ ctrl + shift + r”代替“ manage.py”,并使用“ shift”作为参数。

  1. Add south to your installed apps in project setting file.
  2. Comment out the added/modified field/table.
  3. $ manage.py Schemamigration <app_name> --initial
  4. $ manage.py migrate <app_name> --Fake
  5. Un-comment the field and write the modified one
  6. $ manage.py Schemamigration --auto
  7. $ manage.py migrate <app_name>

If you are using ‘pycharm’, then you can use ‘ctrl+shift+r’ instead of ‘manage.py’ , and ‘shift ‘ for parameters.


声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。