模型字段唯一性验证错误处理



i有一个称为(unique_id)的模型字段,该字段生成随机字符串。它在模型调用帖子中定义。

unique_id = models.CharField(db_index=True, default=generate_id())

generate_id函数是

import random
a = 'ABCDEFJHIJKLMNOPQRSTUVWXYZabcdefjhijklmnopqrstuvwxyz_-123456789'       
def generate_id(length=6):
        return ''.join(random.choice(a) for i in range(length))

django如果不是唯一的话,它将升级IntegrityError: UNIQUE constraint failed

避免在数据库级别上复制唯一ID的正确方法是什么?

首先是@DanielRoseman所说,请勿在default中调用函数,您可以将default值设置为collable,这更好,因为它会在每次创建对象时调用功能,但是如果您调用它在字段定义中,它将在intepret Time

上被调用一次
unique_id = models.CharField(db_index=True, default=generate_id)

其次,我建议使用UUIDField,即为您生成随机字符串。

为了解决您的问题,您有2种方法。产生长长的unique_id,至少12个字符,这几乎会使您不会发生任何碰撞。或者,您可以在generate_id功能中添加DB检查

def generate_id(length=6):
    unique_id = ''.join(random.choice(a) for i in range(length))
    while Mymodel.objects.filter(unique_id=unique_id).exists():
        unique_id = ''.join(random.choice(a) for i in range(length))
    return unique_id

回答评论可以通过self.__class__访问方法中的模型,例如下面的示例

中的模型
class Post(models.Model):
    def _generate_id(self, length=6):
        unique_id = ''.join(random.choice(a) for i in range(length))
        while self.__class__.objects.filter(unique_id=unique_id).exists():
            unique_id = ''.join(random.choice(a) for i in range(length))
        return unique_id

但是,如果它是方法,您将无法将其添加到字段中,因为不会有self实例。但是您可以尝试使用@classmethod装饰器。仅当您在实例化Field对象之前定义_generate_id并且仅与@classmethods一起使用时,这是可能的,因为在Python类中是其自己的小名称空间。

class Post(models.Model):
    @classmethod
    def _generate_id(cls, length=6):
        unique_id = ''.join(random.choice(a) for i in range(length))
        while cls.objects.filter(unique_id=unique_id).exists():
            unique_id = ''.join(random.choice(a) for i in range(length))
        return unique_id
    unique_id = models.CharField(db_index=True, default=_generate_id, max_length=12)

但是我本人在现实生活中从未尝试过。

,因此您的模型声明的问题是您使用了默认的generate_id(),因此该调用的输出被用作默认值。

尝试使用此

unique_id = models.CharField(db_index=True, default=generate_id)

这每次创建对象时都会调用生成ID

参考:https://docs.djangoproject.com/en/1.9/ref/models/fields/#default

最新更新