Django迁移默认值callable生成相同的条目

Django迁移默认值callable生成相同的条目,django,python-3.x,django-migrations,Django,Python 3.x,Django Migrations,我正在向现有db表添加一个新字段。它将使用字符串自动生成。 这是我的密码: 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生成迁移文件,并生成一

我正在向现有db表添加一个新字段。它将使用字符串自动生成。
这是我的密码:

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(默认值=django.utils.crypto.get\u random\u string,最大长度=60)

看来一切都很好。
继续执行
/manage.py migrate
,终端不会出错。 但是,当我检查我的表时,我看到所有
标记
字段都填充了相同的值。

这是不是我做错了什么?
如何在迁移中解决此问题?

它可能是要排序的令牌字符串,因此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
在您的
验证\u令牌字段中

verification_token = models.CharField(max_length=60, unique=True, default=generate_token)

我还建议您使用
unique=True
来处理重复的值。

当一个新列添加到表中,并且该列为
NOT NULL
时,在创建该列的过程中,该列中的每个条目都必须填入有效值。Django通过在列定义中添加一个
DEFAULT
子句来实现这一点。因为这是整个列的一个默认值,所以只调用一次函数

可以使用数据迁移使用唯一值填充列。描述了一个稍微不同的用例的过程,但数据迁移的基础如下:

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()
调用,并更改依赖项以指向应用中的上一次迁移

我最终使用了这个工具,并通过Django迁移解决了一些问题。谢谢,虽然由于django迁移对所有现有行使用一个默认值,所以这不起作用,但请按正确的方向发送给我。