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

Django生成含UserProfile_ID变量的专属URL二维码问题排查

解决Django二维码生成引发的路径参数错误

问题核心

生成用户专属二维码时出现请求路径异常:浏览器发起了/loyalty_card/<qrcode.image.svg.SvgImage object at ...>的请求,导致视图接收的userprofile_id不是预期的数字,而是二维码对象的字符串表示,最终触发数据库查询错误:Field 'id' expected a number but got '<qrcode.image.svg.SvgImage object...>'。

错误原因

模板中直接将qrcode_img(SvgImage对象)赋值给<img>的src属性,Django渲染时会把对象转换成默认的字符串格式,浏览器将该字符串识别为相对路径,发起了错误的GET请求,导致视图接收到非法的参数值。

修复步骤

1. 修正视图:传递SVG字符串而非对象

将生成的SVG图片内容转换成字符串,传递给模板:

from io import BytesIO
import qrcode
from qrcode.image.svg import SvgImage

@login_required
def venue_loyalty_card(request, userprofile_id):
    # 修正查询:使用user_id匹配外键(如果UserProfile的user是外键)
    profile = UserProfile.objects.filter(user_id=userprofile_id)
    itemised_loyalty_cards = Itemised_Loyatly_Card.objects.filter(user_id=userprofile_id)
    
    factory = SvgImage
    stream = BytesIO()
    qrcode_url = f"....com/account/{userprofile_id}/"
    qrcode_img = qrcode.make(qrcode_url, image_factory=factory, box_size=10)
    qrcode_img.save(stream)
    
    # 将SVG内容读取为字符串
    stream.seek(0)
    qrcode_svg = stream.read().decode('utf-8')
 
    return render(request, "main/account/venue_loyalty_card.html", {
        'itemised_loyalty_cards': itemised_loyalty_cards,
        'profile': profile,
        'qrcode_url': qrcode_url,
        'qrcode_svg': qrcode_svg  # 传递SVG字符串
    })

2. 修正模板:使用Data URI展示SVG

将<img>的src改为Data URI,直接嵌入SVG内容:

{% block content %}

<br><br>
Your Loyalty Cards<br>
<br>

<!-- 使用Data URI展示SVG -->
<img style="width: 100%" src="data:image/svg+xml;utf8,{{ qrcode_svg|safe }}">

{% for userprofile in profile %}
    <!-- 可添加用户信息展示逻辑 -->
{% endfor %}

{% for itemised_loyatly_card in itemised_loyalty_cards %}<br>
    {% if request.user.id == itemised_loyatly_card.user.id %} 
        Total Points: {{ itemised_loyatly_card.sum }}<br>
        User : {{ itemised_loyatly_card.user.id }}<br>
        Venue : {{ itemised_loyatly_card.venue }}<br>
        Add points here: {{ itemised_loyatly_card.points }}<br>
    {% endif %}
{% endfor %}
{% endblock %}

3. 修正URL配置:限制参数类型为整数

确保URL只接收数字类型的userprofile_id,避免非法请求进入视图:

path('loyalty_card/<int:userprofile_id>', views.venue_loyalty_card, name="venue-loyalty-card"),

额外优化建议

  • 避免硬编码URL,使用Django的reverse函数生成二维码指向的链接:
    from django.urls import reverse
    qrcode_url = request.build_absolute_uri(reverse('venue-loyalty-card', args=[userprofile_id]))
    
  • 如果UserProfile是一对一关联User模型,使用get_object_or_404获取单个对象,避免空QuerySet:
    from django.shortcuts import get_object_or_404
    profile = get_object_or_404(UserProfile, user_id=userprofile_id)
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 22:16:41