Djangoモデルにnull不可の新しいフィールドを追加し、移行を使用してその変更をデプロイしようとしています。既存のモデルに使用するデフォルト値をそれらの機能にするには定数ではなくモデル?
例として、以前にcreated_on
フィールドがあり、その値を最初にモデルのupdated_on
に設定したいcreated_on
フィールドを追加したとしましょう。移行でこれを行うにはどうすればよいですか?
これは私が始めようとしているものです:
migrations.AddField(
model_name='series',
name='updated_as',
field=models.DateTimeField(default=????, auto_now=True),
preserve_default=False,
),
単一の移行でこれを行う方法を学びました!
makemigrations
Djangoを実行すると、1回限りのデフォルトを設定するように求められます。それを満足させるためにここでできることを定義すれば、移行AddField
あなたが言及しました。
migrations.AddField(
model_name='series',
name='updated_as',
field=models.DateTimeField(default=????, auto_now=True),
),
この1つの操作を3つの操作に変更します。
AlterField
で)変更して、nullを許可しないようにします(上記と同様、デフォルトなし)。そのため、次のような結果になります。
migrations.AddField(
model_name='series',
name='updated_as',
field=models.DateTimeField(null=True, auto_now=True),
),
migrations.RunPython(set_my_defaults, reverse_func),
migrations.AlterField(
model_name='series',
name='updated_as',
field=models.DateTimeField(auto_now=True),
),
あなたの関数は次のようなものとして定義されています:
def set_my_defaults(apps, schema_editor):
Series = apps.get_model('myapp', 'Series')
for series in Series.objects.all().iterator():
series.updated_as = datetime.now() + timedelta(days=series.some_other_field)
series.save()
def reverse_func(apps, schema_editor):
pass # code for reverting migration, if any
あなたが知っていることを除いて、ひどいではありません。 F式 および/または データベース関数 を使用して、大規模データベースの移行パフォーマンスを向上させることを検討してください。
2回の移行で行う必要があります。まず、フィールドを追加しますが、nullを許可します。通常どおり移行ファイルを作成します。その後、フィールドをnull不可に設定し、makemigrationsを再度実行しますが、まだ移行しないでください。 2番目の移行を開き、上部で関数を定義します。
def set_field_values(apps, schema_editor):
# use apps.get_model("app_name", "model_name") and set the defualt values
次に、移行ファイルに操作のリストがあります。 前フィールド変更操作add
RunPython(set_field_values)
そしてそれはそれを行う必要があります
また、将来的に移行を元に戻す場合に備えて、関数set_my_defaults()
のリバースを定義する必要があります。
def reverse_set_default(apps, schema_editor):
pass
この場合の逆関数は、フィールドを削除するため、何もする必要はありません。
それをRunPythonに追加します:
migrations.RunPython(set_my_defaults, reverse_set_default),