代码之家  ›  专栏  ›  技术社区  ›  Ayed

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

  •  0
  • Ayed  · 技术社区  · 9 年前

    我有一个名为(unique_id)的模型字段,它生成一个随机字符串。它在名为Posts的模型中定义。

    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 如果它不是独一无二的。

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

    2 回复  |  直到 9 年前
        1
  •  2
  •   Sardorbek Imomaliev    9 年前

    首先,正如@DanielRoseman所说,不要调用函数 default ,您可以设置 违约 值设置为可调用(callable)更好,因为每次创建对象时它都会调用函数,但如果在字段定义中调用它,则在解释时会调用一次

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

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

    解决问题有两种方法。生成相当长的时间 unique_id ,至少12个字符长,这几乎可以保证不会发生碰撞。或者您可以在您的 generate_id 作用

    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 室内装修设计师只有在您定义了 _generate_id 在实例化之前 Field 对象,它只能与 @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)
    

    但我自己在现实生活中从未尝试过。

        2
  •  0
  •   Vikalp Jain    9 年前

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

    尝试使用此

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

    这将在每次创建对象时调用generate-id

    裁判: https://docs.djangoproject.com/en/1.9/ref/models/fields/#default

    推荐文章