You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)

说明

  1. 设置editable=False:避免在后台管理页面手动修改账号编号,减少人为导致的重复问题。
  2. 重试机制:通过while循环捕获IntegrityError,最多重试5次,既解决低概率的重复冲突,又防止无限循环。
  3. 手动生成编号:调用shortuuid的API生成符合你指定规则(前缀217、纯数字、长度10)的编号,确保格式统一。

内容的提问来源于stack exchange,提问作者wesleys_theory35

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 07:29:59