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?

6 ответов


можно использовать 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 -- to имя класса модели с подчеркиванием между ними.

в случае, когда у вас есть многословное, верблюжье имя модели, такое как ProjectItem, имя таблицы будет app_projectitem (т. е. подчеркивание не будет вставлен между project и item даже если они верблюжьи).


вот что я делаю:

  1. измените имя столбца в своей модели (в этом примере это будет myapp/models.py)
  2. Run ./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')

Я не знал о db.переименовать столбец, звучит удобно, однако в прошлом я добавил новый столбец как одну schemamigration, затем создал datamigration для перемещения значений в новое поле, а затем вторую schemamigration для удаления старого столбца


Django 1.7 представлен миграция так что теперь вам даже не нужно устанавливать дополнительный пакет для управления миграцией.

для переименования модели сначала необходимо создать пустую миграцию:

$ 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>

просто измените модель и запустите makemigrations в 1.9

Django автоматически обнаруживает, что вы удалили и создали одно поле, и спрашивает:

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

скажите "да", и будет создана правильная миграция. Магия.


  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' для параметров.