Django迁移-通过处理现有字段来填充空字段



在更改模型后进行迁移时遇到问题。我将已经存在的DateField(lectures_begginning(从null=true更改为null=false。现在我必须填充旧条目。幸运的是,我有一个DateField(semester_begginning(,它总是设置为null=false。通常这两个相差4-5天,所以我可以复制学期_彩蛋

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')

如何更改迁移,使其仅在selecter_begining为NULL时将semester_beginning的值复制到selectures_begining[/em>?

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ęć'),
),
]

您应该使用make_migration来创建一个空迁移。然后将RunPython操作添加到新迁移的operations列表中。

下面是一个例子(来自Django文档(:

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实例,因为您需要与迁移历史中特定点的数据库架构兼容的版本。

在您的情况下,您可以查询lectures_beginning为null的所有Semester对象。然后迭代结果列表中的对象,复制对象的字段,然后保存对象。(我不认为有什么聪明的方法可以避免编写一些python代码。(

请注意,此数据迁移需要在使用AlterField进行迁移之前进行。我建议将模式和数据迁移操作分开进行迁移。(我不知道如果你尝试将它们组合在一起,它是否会起作用。(

最新更新