Django 迁移默认值可调用生成相同的条目
Django migration default value callable generates identical entry
我正在向现有数据库添加一个新字段 table。它是用字符串自动生成的。
这是我的代码:
from django.utils.crypto import get_random_string
...
Model:
verification_token = models.CharField(max_length=60, null=False, blank=False, default=get_random_string)
我用 ./manage.py makemigrations
生成了我的迁移文件,并生成了一个文件。
我确认新文件的默认设置为 field=models.CharField(default=django.utils.crypto.get_random_string, max_length=60)
看来一切都很好。
继续 ./manage.py migrate
它没有来自终端的错误。
但是,当我检查 table 时,我看到所有 token
字段都填充了相同的值。
这是我做错了什么吗?
我如何在迁移中解决这个问题?
可能是要排序的token字符串,所以django会保存一些重复的值。但是,我不确定这是你的主要问题。
无论如何,我建议您使用 while
处理重复值,然后通过生成的令牌过滤您的模型,确保该令牌尚未使用。我会给你下面的例子..
from django.utils.crypto import get_random_string
def generate_token():
token = get_random_string()
number = 2
while YourModel.objects.filter(verification_token=token).exists():
token = '%s-%d' % (token, number)
number += 1
return token
在你的领域 verification_token
;
verification_token = models.CharField(max_length=60, unique=True, default=generate_token)
我还建议您使用 unique=True
来处理重复值。
将新列添加到 table 时,该列为 NOT NULL
,在创建列期间,列中的每个条目都必须填充有效值。 Django 通过在列定义中添加一个 DEFAULT
子句来做到这一点。由于这是整个列的单个默认值,因此您的函数只会被调用一次。
您可以使用数据迁移使用唯一值填充该列。 in the documentation 描述了一个略有不同的用例的过程,但数据迁移的基础知识如下:
from django.db import migrations, models
from django.utils.crypto import get_random_string
def generate_verification_token(apps, schema_editor):
MyModel = apps.get_model('myapp', 'MyModel')
for row in MyModel.objects.all():
row.verification_token = get_random_string()
row.save()
class Migration(migrations.Migration):
dependencies = [
('myapp', '0004_add_verification_token_field'),
]
operations = [
# omit reverse_code=... if you don't want the migration to be reversible.
migrations.RunPython(generate_verification_token, reverse_code=migrations.RunPython.noop),
]
只需将其添加到新的迁移文件中,更改 apps.get_model()
调用并更改依赖项以指向应用程序中的先前迁移。
我正在向现有数据库添加一个新字段 table。它是用字符串自动生成的。
这是我的代码:
from django.utils.crypto import get_random_string
...
Model:
verification_token = models.CharField(max_length=60, null=False, blank=False, default=get_random_string)
我用 ./manage.py makemigrations
生成了我的迁移文件,并生成了一个文件。
我确认新文件的默认设置为 field=models.CharField(default=django.utils.crypto.get_random_string, max_length=60)
看来一切都很好。
继续 ./manage.py migrate
它没有来自终端的错误。
但是,当我检查 table 时,我看到所有 token
字段都填充了相同的值。
这是我做错了什么吗? 我如何在迁移中解决这个问题?
可能是要排序的token字符串,所以django会保存一些重复的值。但是,我不确定这是你的主要问题。
无论如何,我建议您使用 while
处理重复值,然后通过生成的令牌过滤您的模型,确保该令牌尚未使用。我会给你下面的例子..
from django.utils.crypto import get_random_string
def generate_token():
token = get_random_string()
number = 2
while YourModel.objects.filter(verification_token=token).exists():
token = '%s-%d' % (token, number)
number += 1
return token
在你的领域 verification_token
;
verification_token = models.CharField(max_length=60, unique=True, default=generate_token)
我还建议您使用 unique=True
来处理重复值。
将新列添加到 table 时,该列为 NOT NULL
,在创建列期间,列中的每个条目都必须填充有效值。 Django 通过在列定义中添加一个 DEFAULT
子句来做到这一点。由于这是整个列的单个默认值,因此您的函数只会被调用一次。
您可以使用数据迁移使用唯一值填充该列。 in the documentation 描述了一个略有不同的用例的过程,但数据迁移的基础知识如下:
from django.db import migrations, models
from django.utils.crypto import get_random_string
def generate_verification_token(apps, schema_editor):
MyModel = apps.get_model('myapp', 'MyModel')
for row in MyModel.objects.all():
row.verification_token = get_random_string()
row.save()
class Migration(migrations.Migration):
dependencies = [
('myapp', '0004_add_verification_token_field'),
]
operations = [
# omit reverse_code=... if you don't want the migration to be reversible.
migrations.RunPython(generate_verification_token, reverse_code=migrations.RunPython.noop),
]
只需将其添加到新的迁移文件中,更改 apps.get_model()
调用并更改依赖项以指向应用程序中的先前迁移。