Django views.py报local variable 'verify_payment' referenced before assignment错误求助
问题原因
local variable 'verify_payment' referenced before assignment报错的核心是函数作用域和分支执行逻辑不匹配:
你把verify_payment内部函数定义在了else代码块内,只有当check_pay为True(也就是数据库里存在对应支付记录)的时候,这个函数才会被定义;如果check_pay为False,程序走第一个if分支,只执行了print("Error")就继续往下走,此时verify_payment函数完全没有被定义,调用它自然会触发未赋值错误。
修复方案
你需要调整代码的分支逻辑,保证verify_payment被定义之后才会被调用,同时补全异常分支的处理逻辑,以下是修正后的代码:
import requests import json from datetime import datetime as dt, timedelta from django.conf import settings from django.shortcuts import redirect, render from .models import PayHistory, Membership, UserMembership, Subscription def call_back_url(request): reference = request.GET.get('reference') # 先校验reference是否存在 if not reference: return render(request, 'payment.html', {'error': '缺少支付参考号'}) check_pay = PayHistory.objects.filter(paystack_charge_id=reference).exists() if not check_pay: # 不要只打印错误,直接返回错误状态,避免继续执行后续逻辑 print("错误:对应支付记录不存在") return render(request, 'payment.html', {'error': '支付记录不存在'}) # 走到这里说明记录存在,不需要else嵌套 payment = PayHistory.objects.get(paystack_charge_id=reference) # 把verify_payment挪到分支外定义,或者直接把逻辑写出来不需要嵌套函数 def verify_payment(request): url = f'https://api.paystack.co/transaction/verify/{reference}' headers = { 'Authorization': f'Bearer {settings.PAYSTACK_SECRET_KEY}', 'Content-Type' : 'application/json', 'Accept': 'application/json', } datum = { "reference": payment.paystack_charge_id } x = requests.get(url, data=json.dumps(datum), headers=headers) if x.status_code != 200: return {"status": "fail", "code": x.status_code} return x.json() initialized = verify_payment(request) if initialized.get('data', {}).get('status') == 'success': PayHistory.objects.filter(paystack_charge_id=initialized['data']['reference']).update(paid=True) new_payment = PayHistory.objects.get(paystack_charge_id=initialized['data']['reference']) instance = Membership.objects.get(id=new_payment.payment_for.id) UserMembership.objects.filter(reference_code=initialized['data']['reference']).update(membership=instance) user_membership = UserMembership.objects.get(reference_code=initialized['data']['reference']) Subscription.objects.create( user_membership=user_membership, expires_in=dt.now().date() + timedelta(days=user_membership.membership.duration) ) return redirect('subscribed') return render(request, 'payment.html', {'error': '支付验证失败'}) def subscribed(request): return render(request, 'subscribed.html')
额外优化建议
- 不需要嵌套定义
verify_payment函数,可以直接把验证逻辑写在调用位置,减少不必要的函数嵌套 - 所有数据库查询操作建议加异常捕获,避免查不到对应记录直接抛出500错误
- 调用第三方支付接口的时候建议加超时设置和异常捕获,避免接口超时导致服务卡死
内容的提问来源于stack exchange,提问作者Destiny Franks
相关产品推荐
相关产品推荐

