【问题标题】:Django field with lambda as default value and unique = True以 lambda 为默认值且 unique = True 的 Django 字段
【发布时间】:2015-10-20 14:12:05
【问题描述】:

我基本上得到了这个模型(其他字段省略了):

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 字段的默认值是预先计算的并用于每个新条目,因此它不是每个对象唯一的。我怎样才能让它分别计算每个对象的值?

【问题讨论】:

  • 你能分享一下迁移吗?
  • 如您所见,默认值在您的迁移中是硬编码的。

标签: python django python-2.7 django-1.6


【解决方案1】:

这应该可行:

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 运行更新。

另外,我建议避免将 lambdas 用于默​​认字段选项,并始终检查自动生成的迁移。

【讨论】:

  • 没有注意到您使用的是south。更新了我的答案。
【解决方案2】:

我解决了这个问题。我首先使用 null=True 和 unique=False 创建字段,然后以编程方式为 uuid 字段提供值,然后更改字段以使它们成为 unique=True 并在它们上使用 create_unique。

代码如下:

# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models

import uuid


class Migration(SchemaMigration):

    def forwards(self, orm):
        # Adding field 'Company.uuid'
        db.add_column(u'facebookapp_company', 'uuid',
                      self.gf('django.db.models.fields.CharField')(max_length=32, null=True),
                      keep_default=False)

        # Adding field 'GiftBase.uuid'
        db.add_column(u'facebookapp_giftbase', 'uuid',
                      self.gf('django.db.models.fields.CharField')(max_length=32, null=True),
                      keep_default=False)

        # Adding field 'Purchase.uuid'
        db.add_column(u'facebookapp_purchase', 'uuid',
                      self.gf('django.db.models.fields.CharField')(max_length=32, null=True),
                      keep_default=False)

        for model in (orm.Company, orm.GiftBase, orm.Purchase):
            for obj in model.objects.all():
                obj.uuid = uuid.uuid4().hex
                obj.save()

        db.alter_column(u'facebookapp_company', 'uuid',
                self.gf('django.db.models.fields.CharField')(max_length=32, unique=True, null=False))
        db.create_unique(u'facebookapp_company', ['uuid'])

        db.alter_column(u'facebookapp_giftbase', 'uuid',
                self.gf('django.db.models.fields.CharField')(max_length=32, unique=True, null=False))
        db.create_unique(u'facebookapp_giftbase', ['uuid'])

        db.alter_column(u'facebookapp_purchase', 'uuid',
                self.gf('django.db.models.fields.CharField')(max_length=32, unique=True, null=False))
        db.create_unique(u'facebookapp_purchase', ['uuid'])


    def backwards(self, orm):
        # Deleting field 'Company.uuid'
        db.delete_column(u'facebookapp_company', 'uuid')

        # Deleting field 'GiftBase.uuid'
        db.delete_column(u'facebookapp_giftbase', 'uuid')

        # Deleting field 'Purchase.uuid'
        db.delete_column(u'facebookapp_purchase', 'uuid')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-11
    • 2011-09-04
    • 1970-01-01
    • 1970-01-01
    • 2014-04-11
    • 1970-01-01
    • 1970-01-01
    • 2014-07-06
    相关资源
    最近更新 更多