Skip to main content
 首页 » 编程设计

python之以 lambda 作为默认值且 unique = True 的 Django 字段

2024年10月24日35JeffreyZhao

我基本上得到了这个模型(其他字段被遗漏了):

class GiftBase(models.Model): 
    """ 
        A base class for describing gift type items. 
 
    """ 
    uuid = models.CharField(max_length=32, default=lambda: uuid.uuid4().hex, unique=True) 

当我这样做

./manage.py schemamigration facebookapp --auto 
./manage.py migrate facebookapp 

我得到了这个输出

Running migrations for facebookapp: 
 - Migrating forwards to 0053_auto__add_field_giftbase_uuid__add_field_purchase_uuid. 
 > facebookapp:0053_auto__add_field_giftbase_uuid__add_field_purchase_uuid 
FATAL ERROR - The following SQL query failed: ALTER TABLE "facebookapp_giftbase" ADD COLUMN "uuid" varchar(32) NOT NULL UNIQUE DEFAULT '8de722a747974db3aab4c1fdaa618f16'; 
The error was: could not create unique index "facebookapp_giftbase_uuid_key" 
DETAIL:  Key (uuid)=(8de722a747974db3aab4c1fdaa618f16) is duplicated. 

由此,我意识到 uuid 字段的默认值是预先计算好的,并用于每个新条目,因此它不是每个对象唯一的。我怎样才能让它单独计算每个对象的值?

请您参考如下方法:

这应该有效:

from uuid import uuid4 
 
from django.db.models import Model, CharField 
 
 
def get_default_uuid(): 
    return uuid4().hex 
 
 
class GiftBase(Model): 
    """ 
    A base class for describing gift type items. 
    """ 
    uuid = CharField(max_length=32, default=get_default_uuid, unique=True) 

不要忘记检查自动生成的迁移。如果还有硬编码值,尝试将get_default_uuid直接放到迁移文件中,然后编辑default。

如果要将该列添加到现有表格中,则需要为现有行提供值。

South 会要求您提供一次性值,但据我所知只有 datetime 可用。如果是这样,您可以使用 utcnow.strftime,然后在迁移过程中使用 uuid4 运行更新。

此外,我建议避免将 lambda 用于字段选项(如默认值)并始终检查自动生成的迁移。