1. ホーム
  2. python

[解決済み] Django/South を使ってモデルの名前を変更する最も簡単な方法とは?

2022-05-17 05:57:14

質問

南さんのサイト、Google、SOで回答を探したのですが、簡単な方法が見つかりませんでした。

Southを使ってDjangoのモデルの名前を変更したいです。 以下のようなものがあるとします。

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 から Bar を無視し foo のメンバは無視します。 FooTwo を使うことができます。

Southを使って一番簡単にできる方法は何ですか?

  1. データ移行はできるかもしれませんが、それはかなり複雑なようです。
  2. カスタムマイグレーションを書く、例えば db.rename_table('city_citystate', 'geo_citystate') というように、外部キーを修正する必要がありますが、この場合、どのように修正すればよいのかわかりません。
  3. あなたが知っているより簡単な方法ですか?

どのように解決するのですか?

最初の質問に答えるために、単純なモデル/テーブルの名前の変更は非常に簡単です。コマンドを実行します。

./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 オプションを使うだけです。 クラス名とテーブル名が異なるということは、コードを理解し維持することを難しくします。 私は、明快さのためにこのような単純なリファクタリングを行うことを全面的に支持します。

(更新) 実稼働環境でこれを試したところ、移行を適用しようとしたときに奇妙な警告が表示されました。 それは

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

私は「いいえ」と答えましたが、何も問題ありませんでした。