我刚刚学会了如何通过一次迁移来做到这一点!
跑步时makemigrations
django 应该要求你设置一个一次性的默认值。在这里定义任何你能让它满意的东西,你最终会完成迁移AddField
你提到的。
migrations.AddField(
model_name='series',
name='updated_as',
field=models.DateTimeField(default=????, auto_now=True),
preserve_default=False,
),
将这一项操作改为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 表达式 https://docs.djangoproject.com/en/2.1/ref/models/expressions/ and/or 数据库功能 https://docs.djangoproject.com/en/2.1/ref/models/database-functions/提高大型数据库的迁移性能。