Django应用生成静态二维码时出现404及Battery not found错误求助
问题排查与修复方案
核心问题分析
从错误日志和代码来看,存在两个关键问题:
- URL重复导致404:请求路径为
/fontriden/fontriden/qr_code/...,出现重复的应用前缀,路由无法匹配。 - Battery查询失败:
Battery not found说明数据库中无法通过传入的battery_id找到对应记录,同时代码存在语法错误和参数传递问题。
具体修复步骤
1. 修复URL路由重复问题
若项目根urls.py已通过path('fontriden/', include('fontriden.urls'))将应用路由挂载到/fontriden/下,应用内路由需去掉重复的fontriden/前缀:
修改fontriden/urls.py:
urlpatterns = [ path('qr_code/<str:battery_id>/', views.qr_code_image, name='qr_code_image'), ]
此时reverse('qr_code_image', args=(battery_id,))生成的URL为/fontriden/qr_code/[battery_id]/,可正确匹配路由。
2. 修复battery_registration_success语法错误
该函数的context字典未闭合,存在语法错误,需补充完整:
修改views.py中的battery_registration_success:
def battery_registration_success(request): w3 = Web3(Web3.HTTPProvider("http://127.0.0.1:7545")) contract = w3.eth.contract(address=CONTRACT_ADDRESS, abi=contract_abi) battery_id = request.session.get('battery_id') numeric_battery_id = int(battery_id, 16) qr_code_url = reverse('qr_code_image', args=(battery_id,)) battery_details = get_battery_details(w3, contract, battery_id) context = { 'battery_details': { 'battery_id': battery_id, 'product_name': battery_details[0], 'certification_mark': battery_details[1], 'serial_number': battery_details[2], 'watt_hours': battery_details[3], 'qr_code_url': qr_code_url, } } return render(request, 'battery_registration_success.html', context)
3. 修复qr_code_image的参数与查询问题
- 调用
generate_qr_code时参数缺失,需先获取battery_details再传参; - 确保查询Battery时使用的
battery_id与数据库存储的id完全一致。
修改views.py中的qr_code_image:
def qr_code_image(request, battery_id): try: battery = Battery.objects.get(id=battery_id) except Battery.DoesNotExist: raise Http404("Battery not found") # 需确保get_battery_details能正确获取w3和contract参数,或提前在函数内初始化 w3 = Web3(Web3.HTTPProvider("http://127.0.0.1:7545")) contract = w3.eth.contract(address=CONTRACT_ADDRESS, abi=contract_abi) battery_details = get_battery_details(w3, contract, battery_id) qr_code_filepath = generate_qr_code(battery, battery_details) context = { 'battery_details': { 'battery_id': battery.id, 'product_name': battery_details[0], 'certification_mark': battery_details[1], 'serial_number': battery_details[2], 'watt_hours': battery_details[3], 'qr_code_filepath': qr_code_filepath, } } return render(request, 'generate_qrcode.html', context)
4. 修复二维码路径的访问问题
Django无法直接解析本地文件路径,需将二维码目录配置为媒体目录:
- 在项目
settings.py添加媒体配置:
MEDIA_ROOT = os.path.join(BASE_DIR, 'media') MEDIA_URL = '/media/'
- 修改
generate_qr_code的生成路径:
def generate_qr_code(battery, battery_details): qr_code_filename = f'battery_qr_{battery.id}.png' qr_code_filepath = os.path.join(settings.MEDIA_ROOT, 'qr_codes', qr_code_filename) # 确保目录存在 os.makedirs(os.path.dirname(qr_code_filepath), exist_ok=True) details = f"Product Name: {battery_details[0]}\nCertification Mark: {battery_details[1]}\nSerial Number: {battery_details[2]}\nWatt Hours: {battery_details[3]}" qr = qrcode.QRCode(version=1, error_correction=qrcode.constants.ERROR_CORRECT_H, box_size=5, border=4) qr.add_data(details) qr.make(fit=True) qr_image = qr.make_image(fill_color="black", back_color="white") qr_image.save(qr_code_filepath) # 返回媒体URL相对路径 return os.path.join(settings.MEDIA_URL, 'qr_codes', qr_code_filename)
- 在项目根
urls.py添加媒体路由:
from django.conf import settings from django.conf.urls.static import static urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
5. 验证Battery记录保存逻辑
确保注册电池时,将生成的battery_id正确赋值给Battery模型的id主键:
# 示例注册逻辑 def battery_registration(request): if request.method == 'POST': # 处理表单数据... battery_id = "生成的十六进制唯一ID" Battery.objects.create( id=battery_id, product_name=form.cleaned_data['product_name'], certification_mark=form.cleaned_data['certification_mark'], serial_number=form.cleaned_data['serial_number'], watt_hours=form.cleaned_data['watt_hours'], manufacturer=request.user.manufacturer ) request.session['battery_id'] = battery_id return redirect('battery_registration_success')
内容的提问来源于stack exchange,提问作者Koyemushi
相关产品推荐
相关产品推荐

