Django模型唯一字段规避IntegrityError:自动生成新唯一值
解决方案:自动生成唯一账号编号避免IntegrityError
针对你遇到的问题——设置unique=True后重复值会抛出IntegrityError,可以通过重写模型的save方法,捕获冲突异常并重试生成新编号,实现自动生成唯一值的需求。
重写Account模型的save方法
直接在Account模型中添加重试逻辑,当保存时遇到账号编号重复的异常,就重新生成新编号直到保存成功:
from django.db import IntegrityError import shortuuid from django.contrib.auth.models import User from shortuuidfield import ShortUUIDField class Account(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) # 添加editable=False,避免后台手动修改导致冲突 account_number = ShortUUIDField(unique=True, length=10, max_length=25, prefix="217", alphabet="1234567890", editable=False) def save(self, *args, **kwargs): # 仅对新建实例处理(修改实例时不重新生成编号) if not self.pk: max_retries = 5 # 设置最大重试次数,防止极端情况无限循环 retry_count = 0 while retry_count < max_retries: try: # 手动生成符合规则的账号编号 self.account_number = f"217{shortuuid.ShortUUID(alphabet='1234567890').random(length=10)}" # 调用父类的save方法保存 super().save(*args, **kwargs) return except IntegrityError: # 遇到重复则重试 retry_count += 1 # 超过重试次数仍失败,抛出异常(可根据业务需求调整,比如记录日志) raise IntegrityError("无法生成唯一账号编号,请稍后重试") # 已有主键的实例,直接保存 else: super().save(*args, **kwargs)
说明
- 设置
editable=False:避免在后台管理页面手动修改账号编号,减少人为导致的重复问题。 - 重试机制:通过
while循环捕获IntegrityError,最多重试5次,既解决低概率的重复冲突,又防止无限循环。 - 手动生成编号:调用
shortuuid的API生成符合你指定规则(前缀217、纯数字、长度10)的编号,确保格式统一。
内容的提问来源于stack exchange,提问作者wesleys_theory35
相关产品推荐
相关产品推荐

