2016-03-14 11 views
5

私のDjangoモデルのフィールドのタイプをCharFieldからForeignKeyに変更する必要があります。フィールドにはすでにデータが設定されているため、これを行うにはどのような方法が最適か、また正しいか不思議でした。フィールドのタイプを更新して移行することはできますか、それとも気付いている可能性がありますか? N.B:私はバニラDjango管理操作(makemigrationsmigrate)を使用しますが、南は使用しません。CharFieldからForeignKeyへのDjangoモデルフィールドのタイプの変更

+2

CharFieldに一意の制約がない場合は、重複する値に注意してください。以前はデータを複製していたのか、それともそれを自分のテーブルに移動したいのかが本当に異なります。後者の場合、実際に行うべき最良のことは、あなたのデータが意味するものに依存します。 DjangoはCharFieldとForeignKeyの間で何らかの魔法の変換を推論することはできません。自分で賢明な移行を書く必要があります。 – user234461

+1

これはあなたが探しているものに似ていると思います。 http://stackoverflow.com/questions/5373906/changing-the-django-data-type-in​​-models-with-droping-the-table – Vibhu

答えて

25

これは、多段階の移行を実行したい場合です。私の推薦は以下のようになります。

まず第一に、アプリケーションがdiscographyと呼ばれる内側のは、これはあなたの最初のモデルであると仮定してみましょう:

from django.db import models 

class Album(models.Model): 
    name = models.CharField(max_length=255) 
    artist = models.CharField(max_length=255) 

は今、あなたはあなたの代わりに、アーティストのためのForeignKeyを使用することを実現します。言いましたが、これは単なる単純なプロセスではありません。それはいくつかのステップで行われなければならない。

ステップ1、ヌルとしてそれをマークすることを確認すること、ForeignKeyのための新しいフィールドを追加します。

from django.db import models 

class Album(models.Model): 
    name = models.CharField(max_length=255) 
    artist = models.CharField(max_length=255) 
    artist_link = models.ForeignKey('Artist', null=True) 

class Artist(models.Model): 
    name = models.CharField(max_length=255) 

...と、この変更の移行を作成します。

./manage.py makemigrations discography 

ステップ2、新しいフィールドを入力します。これを行うには、空の移行を作成する必要があります。

./manage.py makemigrations --empty --name transfer_artists discography 

あなたはこの空の移行を持っていたら、あなたはあなたの記録をリンクするために、それに単一RunPython操作を追加します。この場合、それはこのような何かを見ることができる:

def link_artists(apps, schema_editor): 
    Album = apps.get_model('discography', 'Album') 
    Artist = apps.get_model('discography', 'Artist') 
    for album in Album.objects.all(): 
     artist, created = Artist.objects.get_or_create(name=album.artist) 
     album.artist_link = artist 
     album.save() 

は今、あなたのデータを新しいフィールドに転送されていることを、あなたが実際に行うことができるとあるようにすべてのための新しいフィールドを使用して、すべてのものを残します。または、少しクリーンアップを行いたい場合は、2つ以上のマイグレーションを作成する必要があります。

最初の移行では、元のフィールドartistを削除します。 2回目の移行では、新しいフィールドartist_linkの名前をartistに変更します。

これは、Djangoが正しく操作を認識できるように、複数のステップで実行されます。これを処理するために手動で移行を作成することもできますが、それを把握しておきます。

+0

迅速で包括的な回答をいただきありがとうございます。これはまた私が最後に座って、Djangoの移行について正しく学ぶことを刺激しました! – ChrisM

+0

'./manage.py makemigrations --empty ...'ではないでしょうか?ステップ2には「makemigration」(単数形)があります。 – ChrisM

+0

ああ、はい、タイプミスをキャッチしてくれてありがとう! –

関連する問題