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

Django中重复随机兑换码重新生成后无法存入数据库的问题

问题分析:兑换码重复时无法保存到数据库

问题场景

在用户下单生成随机兑换码的逻辑中,当生成的兑换码已存在时,GetRandomRedeemCode函数重新生成的新码无法被Django保存到数据库。

相关代码

下单处理函数

def CompleteOrder(request):
    order_qs = Purchase.objects.filter(user=request.user, ordered=False)
    if order_qs:
        specific_order = order_qs[0]
        for order in specific_order.product_purchased.all():
            order.item.purchased_by.add(request.user)
        specific_order.ordered = True
        specific_order.total_price = specific_order.get_total()
        specific_order.redeem_code = GetRandomRedeemCode()
        specific_order.save()
        return redirect("OrderCompletedSuccessURL")

兑换码生成函数

def GetRandomRedeemCode():
    random_num = str(random.randint(10000000,99999999))
    if Purchase.objects.filter(redeem_code=random_num).exists():
        GetRandomRedeemCode()
    else:
        return random_num

核心原因

GetRandomRedeemCode函数的递归调用没有返回值。当第一次生成的兑换码已存在时,函数进入if分支调用自身,但没有将递归生成的新兑换码返回给上层调用。这会导致函数最终返回None,而不是新生成的有效兑换码,因此Django无法将有效的兑换码保存到数据库中。

修复方案

修改GetRandomRedeemCode函数,在递归调用时添加return,确保新生成的兑换码能正确返回:

def GetRandomRedeemCode():
    random_num = str(random.randint(10000000,99999999))
    if Purchase.objects.filter(redeem_code=random_num).exists():
        # 添加return,将递归生成的兑换码返回
        return GetRandomRedeemCode()
    else:
        return random_num

额外优化建议

  • 递归调用存在栈溢出风险(虽然8位数字的重复概率极低),可以改用循环实现,更安全:
def GetRandomRedeemCode():
    while True:
        random_num = str(random.randint(10000000,99999999))
        if not Purchase.objects.filter(redeem_code=random_num).exists():
            return random_num
  • 可以给redeem_code字段添加唯一约束(unique=True),从数据库层面保证唯一性,避免并发场景下的重复问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 03:35:21