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)

какой самый простой способ сделать это через юг?

6 205

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 даже если они в стиле Camel).

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

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

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

Джанго 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', и 'сдвиг' для параметров.