在更改模型后进行迁移时遇到问题。我已经将exisitnig DateField( lectures_begginning )从null=true
更改为null=false
。现在,我必须填充旧条目。幸运的是,我有一个现有的DateField( semester_begginning ),该字段始终设置为null=false
。通常这两个时间相差4-5天,因此我可以复制 semester_beggining 。
class Semester(models.Model):
lectures_beginning = models.DateField(
null=False, verbose_name='Class start day')
semester_beginning = models.DateField(
null=False, verbose_name='Semester start day')
如何更改迁移,以便仅在后者为NULL时将 semester_beginning 的值复制到 lectures_beginning ?
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('courses', '0034_auto_20201106_2039'),
]
operations = [
migrations.AlterField(
model_name='semester',
name='lectures_beginning',
field=models.DateField(verbose_name='Dzień rozpoczęcia zajęć'),
),
]
答案 0 :(得分:0)
您应该使用make_migration
创建一个空迁移。然后将RunPython
操作添加到新迁移的operations
列表中。
以下是一个示例(来自Django documentation):
from django.db import migrations
def combine_names(apps, schema_editor):
# We can't import the Person model directly as it may be a newer
# version than this migration expects. We use the historical version.
Person = apps.get_model('yourappname', 'Person')
for person in Person.objects.all():
person.name = '%s %s' % (person.first_name, person.last_name)
person.save()
class Migration(migrations.Migration):
dependencies = [
('yourappname', '0001_initial'),
]
operations = [
migrations.RunPython(combine_names),
]
如注释中所述,您必须使用apps
来检索Model实例,因为您需要一个与迁移历史记录中特定点的数据库架构兼容的版本。
在您的情况下,您可以查询Semester
为空的所有lectures_beginning
对象。然后迭代结果列表中的对象,复制该对象的字段,然后保存该对象。 (我认为没有一种聪明的方法可以避免编写一些python代码。)
请注意,此数据迁移需要在使用AlterField
进行迁移之前进行。我建议保持将架构和数据迁移操作放在单独的迁移中。 (我不知道如果您尝试将它们结合起来是否可行。)