Django - Как переименовать поле модели, используя South?

214

Я хотел бы изменить имя определенных полей в модели:

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

должен измениться на:

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

Какой самый простой способ сделать это с помощью Юга?

Теги:
django-models
django-south

6 ответов

227
Лучший ответ

Вы можете использовать функцию 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 автоматически выводит имя таблицы базы данных из имени вашего класса модели и приложения, которое его содержит. Имя таблицы базы данных модели создается путем присоединения к модели "метка приложения" - имя, которое вы использовали в файле управления .py startapp - с именем класса модели, с подчеркиванием между ними.

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

  • 2
    Это будет работать на имя \ полное_имя, но не на поле отношения, верно?
  • 0
    Я попытался db.rename_column ('app_foo', 'rel', 'odd_relation') и получил: _mysql_exceptions.OperationalError: (1025, "Ошибка при переименовании". \\ ap_site \\ # sql-1034_20 "в". \\ " my_app_db \\ app_foo '(errno: 150) ")
Показать ещё 10 комментариев
39

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

  • Изменить имя столбца в вашей модели (в этом примере это будет myapp/models.py)
  • Выполнить ./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')
  • 0
    как называется столбец в вашей команде? x или column_x ?
  • 0
    Часть команды, на которую вы ссылаетесь, просто используется для обозначения миграции, она может быть любой, какой вам нравится. Имя столбца необходимо будет указать в файле миграции при его редактировании.
Показать ещё 4 комментария
15

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

  • 0
    Я тоже. Проблема с техникой schema-data-schema заключается в том, что в итоге вы получаете разные имена для ваших полей / моделей. Иногда это проблема, если вы используете канонические имена для включения диспетчеров ...
  • 0
    Я просто попробовал это, и это не сработало, потому что был конфликт имен. У меня был точно такой же FK, но другое имя. Это не подтвердило. Так что не делай этого.
Показать ещё 3 комментария
9

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

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

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

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

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

0
  • Добавьте south к установленным приложениям в файл настроек проекта.
  • Прокомментируйте добавленное/измененное поле/таблицу.
  • $ manage.py Schemamigration <app_name> --initial
  • $ manage.py migrate <app_name> --Fake
  • Отмените комментарий к полю и напишите измененный
  • $ manage.py Schemamigration --auto
  • $ manage.py migrate <app_name>

Если вы используете "pycharm", вы можете использовать "ctrl + shift + r" вместо "manage.py" и "shift" для параметров.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню