我想在现有模型中添加一个新字段。出于向后兼容性的原因,我想要两个默认值:
我可以看到在迁移中添加字段的代码非常简单:
if (!form2.IsHandleCreated)
{
form2.CreateControl();
}
form2.Invoke((MethodInvoker) delegate
{
//Do Stuff Here.
}
但是,我看不到应该在哪里添加旧版默认值。
PS:说实话,我根本不希望在迁移中使用默认的默认设置。我更希望将其设置在operations = [
migrations.AddField(
model_name='queue',
name='permission_name',
field=models.CharField(help_text='Name used in the django.contrib.auth permission system', max_length=50, null=True, verbose_name='Django auth permission name', blank=True),
),
]
中,以便阅读代码的人很清楚发生了什么。但是我认为它必须在迁移中,而我将在models.py
中留下评论。
答案 0 :(得分:1)
似乎没有任何方法可以在models.py
中指定旧式默认值,但是通过迁移可以很容易地做到这一点。
例如,如果将新迁移secret_key
添加到模型票证,则将为此新字段创建两个迁移。一次迁移将字段添加为可为空的字段,随后使用RunPython
设置旧版默认值。
from django.db import migrations, models
import helpdesk.models
def clear_secret_keys(apps, schema_editor): # set the legacy default
Ticket = apps.get_model("helpdesk", "Ticket")
db_alias = schema_editor.connection.alias
for ticket in Ticket.objects.using(db_alias).all():
ticket.secret_key='<legacy-default>'
ticket.save()
class Migration(migrations.Migration):
dependencies = [
('helpdesk', '0017_default_owner_on_delete_null'),
]
operations = [
migrations.AddField(
model_name='ticket',
name='secret_key',
field=models.CharField(default='<default-for-new-objects>', max_length=36, null=True, verbose_name='Secret key needed for viewing/editing ticket by non-logged in users'),
),
migrations.RunPython(clear_secret_keys),
]
如果您不希望字段为空,则需要创建第二次迁移,以将字段更改为不可空:
from django.db import migrations, models
import helpdesk.models
class Migration(migrations.Migration):
dependencies = [
('helpdesk', '0018_ticket_secret_key'),
]
operations = [
migrations.AlterField(
model_name='ticket',
name='secret_key',
field=models.CharField(default='<default-for-new-objects>', max_length=36, verbose_name='Secret key needed for viewing/editing ticket by non-logged in users'),
),
]
写出这个答案后,我想到有另一种方法可以进行此操作,也可以进行两次迁移,即首先设置旧版默认值,然后再使用新对象的默认值:
from django.db import migrations, models
import helpdesk.models
class Migration(migrations.Migration):
dependencies = [
('helpdesk', '0017_default_owner_on_delete_null'),
]
operations = [
migrations.AddField(
model_name='ticket',
name='secret_key',
field=models.CharField(default='<legacy-default>', max_length=36, null=True, verbose_name='Secret key needed for viewing/editing ticket by non-logged in users'),
),
]
如果您不希望字段为空,则需要创建第二次迁移,以将字段更改为不可空:
from django.db import migrations, models
import helpdesk.models
class Migration(migrations.Migration):
dependencies = [
('helpdesk', '0018_ticket_secret_key'),
]
operations = [
migrations.AlterField(
model_name='ticket',
name='secret_key',
field=models.CharField(default=helpdesk.models.mk_secret, max_length=36, verbose_name='Secret key needed for viewing/editing ticket by non-logged in users'),
),
]
这两种方法甚至都适用于动态默认值。例如,在这种情况下,新对象的默认设置是称为helpdesk.models.mk_secret
的方法,该方法为所有新创建的对象生成唯一的uuid。