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

Django应用生成静态二维码时出现404及Battery not found错误求助

问题排查与修复方案

核心问题分析

从错误日志和代码来看,存在两个关键问题:

  1. URL重复导致404:请求路径为/fontriden/fontriden/qr_code/...,出现重复的应用前缀,路由无法匹配。
  2. 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无法直接解析本地文件路径,需将二维码目录配置为媒体目录:

  1. 在项目settings.py添加媒体配置:
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
  1. 修改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)
  1. 在项目根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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 00:47:01