简体   繁体   English

作为callable的默认值仅在django迁移期间调用一次

[英]default value as callable is only called once during django migration

I've created the following basic django model : 我创建了以下基本的django模型:

import string
import random

from django.db import models

def create_short_url():
    size = 6
    chars = string.ascii_uppercase + string.digits
    url = ''.join(random.choice(chars) for _ in range(size))
    print("\nSHORT_URL:%s\n" % url)
    return url

class ShortURL(models.Model):
    url = models.CharField(max_length=220, )
    shortcode = models.CharField(max_length=15, unique=True, default=create_short_url)

    def __str__(self):
        return str(self.url)

First I only coded the url field. 首先,我只编写了url字段。 Then I added the shortcode field and provided a function to be called to create default unique values. 然后我添加了shortcode字段并提供了一个函数来调用以创建默认的唯一值。 Django's documentation says Django的文档说

If callable it will be called every time a new object is created. 如果可调用,则每次创建新对象时都会调用它。

Unfortunately, when running the migration, I see only one short url generated and the following exception : 不幸的是,在运行迁移时,我看到只生成了一个短网址,并出现以下异常:

$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions, shortener
Running migrations:
  Applying shortener.0002_auto_20161107_1529...
SHORT_URL:43AY7G

Traceback (most recent call last):
  File "/home/user/django1.10/py3/lib/python3.5/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "/home/user/django1.10/py3/lib/python3.5/site-packages/django/db/backends/sqlite3/base.py", line 337, in execute
    return Database.Cursor.execute(self, query, params)
sqlite3.IntegrityError: UNIQUE constraint failed: shortener_shorturl.shortcode

What is missing to call that function for each entry being migrated? 为每个要迁移的条目调用该函数缺少什么?

Initially, you will need to defer the unique constraint on the shortcode field and permit null values and then re-create and run your migration.(don't forget to remove the migration that fails) 最初,您需要在短代码字段上推迟唯一约束并允许空值,然后重新创建并运行迁移。(不要忘记删除失败的迁移)

class ShortURL(models.Model):
    url = models.CharField(max_length=220, )
    shortcode = models.CharField(max_length=15, null=True)

    def __str__(self):
        return str(self.url)

After that, 1) create a new empty migration and add a RunPython operation that leverages your create_short_url(). 之后,1)创建一个新的空迁移并添加一个利用create_short_url()的RunPython操作。 2)change your model to your original definition and create a new auto migration and run it. 2)将模型更改为原始定义并创建新的自动迁移并运行它。

Refer here for more information: Migrations that add unique fields 有关更多信息,请参阅此处: 添加唯一字段的迁移

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM