我刚刚学会了如何通过一次迁移来做到这一点!
当运行makemigrations django 时应该要求你设置一个一次性的默认值。在这里定义任何你可以让它快乐的东西,你最终会得到你提到的迁移AddField。
migrations.AddField(
model_name='series',
name='updated_as',
field=models.DateTimeField(default=????, auto_now=True),
preserve_default=False,
),
把这1个操作改成3个操作:
- 最初使该字段可以为空,因此将添加该列。
- 调用函数以根据需要填充字段。
- 更改字段(使用
AlterField)使其不可为空(如上,无默认值)。
所以你最终会得到这样的结果:
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 expressions 和/或database functions 来提高大型数据库的迁移性能。