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

在Django中如何提取产品序列号字符串末尾数字并转换为Int实现自增

Django 产品序列号生成逻辑修正方案

原有代码核心问题

  • 年份判断逻辑错误:年份为4位数字,原有代码截取序列号前3位[0:3]进行判断,永远无法和当前4位年份匹配
  • 变量号提取&自增逻辑错误:序列号末尾的变量号为3位,原有代码仅截取最后1位[-1],且自增运算符写反为=+1,实际效果是直接赋值为1,无法实现自增
  • 初始变量号不符合规则:需求中初始变量号为101,原有代码赋值为10,输出结果不符合序列号规则
  • 代码冗余:三个分支中年份前缀、产品名称缩写的赋值逻辑完全重复,可统一提取
  • 并发场景隐患:直接调用last()取最后一条记录,高并发场景下会出现重复生成序列号的问题,生产环境建议加数据库事务或者唯一索引约束

修正后代码

import datetime
from django.db import transaction

if serialNumberForm.is_valid():
    os = serialNumberForm.save(commit=False)
    # 统一提取公共配置
    current_year = datetime.date.today().year
    # 产品名称缩写增加长度校验,避免下标越界
    product_name = product.nome.strip()
    fix = product_name[3:6] if len(product_name) >=6 else product_name[:2].upper()
    suffix = Produto.id

    # 加事务和行锁避免并发重复问题
    with transaction.atomic():
        lastProduct = NumeroSerie.objects.select_for_update().last()
        # 无历史记录或跨年时,变量号从初始值101开始
        if not lastProduct or int(lastProduct.serialNumber[:4]) != current_year:
            var = 101
        else:
            # 提取最后3位变量号转数字后自增
            last_var = int(lastProduct.serialNumber[-3:])
            var = last_var + 1
        # 拼接生成最终序列号
        os.serialNumber = f"{current_year}{fix}{suffix}{var}"
        os.save()

补充优化建议

  • 建议给NumeroSerie表的serialNumber字段加唯一索引,避免极端场景下出现重复值
  • 产品名称缩写的截取逻辑可根据实际业务调整,上述代码加了长度兜底逻辑,避免产品名过短时报错
  • 如果需要固定变量号为3位,不足时前面补0,可以把变量号拼接逻辑改成f"{var:03d}",超出3位时会自动延长不会截断

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 12:06:02