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
相关产品推荐
相关产品推荐

