Самый простой способ переименовать модель с помощью Django / South?
Я искал ответ на это на сайте Юга, Google, и так, но не мог найти простой способ сделать это.
Я хочу переименовать модель Django с помощью South. Скажем, у вас есть следующее:
class Foo(models.Model):
name = models.CharField()
class FooTwo(models.Model):
name = models.CharField()
foo = models.ForeignKey(Foo)
и вы хотите конвертировать Foo в Bar, а именно
class Bar(models.Model):
name = models.CharField()
class FooTwo(models.Model):
name = models.CharField()
foo = models.ForeignKey(Bar)
чтобы все было просто, я просто пытаюсь изменить имя с Foo
to Bar
, но игнорировать foo
член FooTwo
сейчас.
какой самый простой способ сделать это использование Юга?
- я, вероятно, мог бы сделать миграцию данных, но это кажется довольно сложным.
- напишите пользовательскую миграцию, например
db.rename_table('city_citystate', 'geo_citystate')
, но я не уверен, как исправить внешний ключ в этом случае. - простой способ, который вы знаете?
4 ответов
чтобы ответить на ваш первый вопрос, простое переименование модели/таблицы довольно просто. Выполните команду:
./manage.py schemamigration yourapp rename_foo_to_bar --empty
(обновление 2: попробовать --auto
вместо --empty
чтобы избежать предупреждения ниже. Спасибо @KFB за подсказку.)
если вы используете более старую версию south, вам понадобится startmigration
вместо schemamigration
.
затем вручную отредактируйте файл миграции, чтобы он выглядел так:
class Migration(SchemaMigration):
def forwards(self, orm):
db.rename_table('yourapp_foo', 'yourapp_bar')
def backwards(self, orm):
db.rename_table('yourapp_bar','yourapp_foo')
вы можете выполнить это более просто используя db_table
Meta вариант в вашем классе модели. Но каждый раз, когда вы это делаете, вы увеличиваете унаследованный вес вашей кодовой базы-наличие имен классов отличается от имен таблиц делает ваш код сложнее понять и поддерживать. Я полностью поддерживаю выполнение простых рефакторингов, подобных этому, ради ясности.
(обновление) я просто попробовал это в производстве и получил странное предупреждение, когда я пошел применять миграцию. Он сказал:"!--9-->
The following content types are stale and need to be deleted: yourapp | foo Any objects related to these content types by a foreign key will also be deleted. Are you sure you want to delete these content types? If you're unsure, answer 'no'.
я ответил "Нет" и казалось, все в порядке.
внести изменения в models.py
и затем запустить
./manage.py schemamigration --auto myapp
при проверке миграционного файл, вы увидите, что он удаляет таблицу и создает новую
class Migration(SchemaMigration):
def forwards(self, orm):
# Deleting model 'Foo'
db.delete_table('myapp_foo')
# Adding model 'Bar'
db.create_table('myapp_bar', (
...
))
db.send_create_signal('myapp', ['Bar'])
def backwards(self, orm):
...
это не совсем то, что вы хотите. Вместо этого отредактируйте миграцию так, чтобы она выглядела так:
class Migration(SchemaMigration):
def forwards(self, orm):
# Renaming model from 'Foo' to 'Bar'
db.rename_table('myapp_foo', 'myapp_bar')
if not db.dry_run:
orm['contenttypes.contenttype'].objects.filter(
app_label='myapp', model='foo').update(model='bar')
def backwards(self, orm):
# Renaming model from 'Bar' to 'Foo'
db.rename_table('myapp_bar', 'myapp_foo')
if not db.dry_run:
orm['contenttypes.contenttype'].objects.filter(app_label='myapp', model='bar').update(model='foo')
в отсутствие update
заявление db.send_create_signal
вызов создаст новый ContentType
С новым именем модели. Но лучше просто update
на ContentType
у вас уже есть в если на него указывают объекты базы данных (например, через GenericForeignKey
).
кроме того, если вы переименовали некоторые столбцы, которые являются внешними ключами к переименованной модели, не забудьте
db.rename_column(myapp_model, foo_id, bar_id)
Юг не может сделать это сам - откуда он знает, что Bar
означает, что Foo
раньше? Это то, для чего я бы написал пользовательскую миграцию. Вы можете изменить свой ForeignKey
в коде, как вы сделали выше, и тогда это просто случай переименования соответствующих полей и таблиц, которые вы можете сделать любым удобным вам способом.
наконец, вам действительно нужно это сделать? Мне еще нужно переименовать модели - имена моделей - это просто деталь реализации , особенно учитывая наличие verbose_name
Meta вариант.
Я следил за решением Леопда выше. Но это не изменило названия моделей. Я изменил его вручную в коде (также в связанных моделях, где это называется FK). И сделал еще одну миграцию на юг, но с ... поддельным вариантом. Это делает имена моделей и таблиц одинаковыми.
только что понял, можно сначала начать с изменения имен моделей, а затем отредактировать файл миграции перед их применением. Более чистый.