Bri*_*HVB 2 python django postgresql
我理解并非常清楚传递函数作为参数与调用函数以及结果作为参数之间的区别。我相信我正确地传递了功能。
我的应用程序中有数十个模型,并且有许多现有记录。我需要向每个模型添加随机种子,这些种子将在创建新模型实例时创建和设置。我还想为现有实例生成随机种子。
我对Django模型默认设置和Migrations如何工作的理解是,当向模型添加新字段时,如果该字段设置了默认值,Djano将使用新字段和相应的默认值更新所有现有实例。
但是,尽管事实上我肯定会传递一个函数作为默认值,并且该函数会产生一个随机数,但是Django在更新现有行时会使用相同的随机数(例如,Djano似乎只调用了一次函数,然后使用所有条目的返回值)。
我的代码的简化版:
def get_random():
return str(random.random())
class Response(models.Model):
# various properties
random = models.CharField(max_length=40, default=get_random)
user = models.ForeignKey(User, on_delete=models.CASCADE)
content = JSONField(null=True)
Run Code Online (Sandbox Code Playgroud)
在模型和它的许多实例已经创建之后,将添加随机字段。makemigrations出现一条命令来生成正确的迁移文件,并带有一个migrations.AddField()调用,并将其default=get_random作为参数传入。
但是,运行后makemigrations,所有现有的现有Response实例在其随机字段中都包含完全相同的数字。创建和保存模型的新实例将按预期方式工作(使用伪唯一随机数)。
一个简单的解决方法是只运行一次脚本
for r in Response.objects.all():
r.random = get_random()
r.save()
Run Code Online (Sandbox Code Playgroud)
或覆盖模型的save()方法,然后进行批量保存。但我认为这些变通办法不是必需的。这也意味着,如果我想使用随机默认值创建唯一字段,那么我将需要多次迁移。首先,我必须添加具有指定默认值的字段。接下来,我将需要应用迁移并手动重新初始化字段值。然后进行第二次迁移以添加unique=True属性。
看来,如果Django要在上将默认值应用于现有实例,makemigrations则应使用与创建新实例相同的语义来应用默认值。有什么方法可以强制Django在迁移时为每个模型实例调用函数?
要将非空列添加到现有表中,Django需要使用ALTER TABLE ADD COLUMN ... DEFAULT <default_value>。这仅允许Django调用一次默认函数,这就是为什么您看到每一行都具有相同值的原因。
除了可以使用数据迁移用唯一值填充现有行之外,您的解决方法很重要,因此不需要任何手动步骤。此用例的整个过程在docs中进行了描述:https : //docs.djangoproject.com/en/2.1/howto/writing-migrations/#migrations-that-add-unique-fields