我刚学会了如何使用单个迁移来完成这个操作!
当运行makemigrations
时,django会要求你设置一个一次性的默认值。在此定义任何东西以使其正常,然后你将得到你提到的迁移AddField
。
migrations.AddField(
model_name='series',
name='updated_as',
field=models.DateTimeField(default=????, auto_now=True),
preserve_default=False,
),
将这个操作拆分为三个操作:
- 最开始将该字段设置为可空的,这样就可以添加该列。
- 调用函数按需填充字段。
- 使用
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
除了,你知道的,不算糟糕。
注意:考虑使用F表达式和/或数据库函数来提高大型数据库的迁移性能。
update函数作为单个请求运行。
- Искрен Станиславовmigrations.RunPython.noop
代替reverse_func
。请查看文档以获取进一步的细节 - https://docs.djangoproject.com/en/2.1/ref/migration-operations/#django.db.migrations.operations.RunPython.noop - Fusion