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

Django集成Tranzila支付网关时遇TypeError: quote_from_bytes() expected bytes

解决Django集成Tranzila时的TypeError及购物车数据传输问题

你遇到的核心问题有两个:一是quote()函数的参数类型错误,二是购物车数据的JSON构建方式不符合Tranzila的要求。我来一步步帮你解决:

错误原因分析

你当前代码里,cart_data是一个包含多个独立JSON字符串的列表,然后直接把这个列表传给quote()——但urllib.parse.quote()只接受字符串或字节类型,不接受列表,这就触发了quote_from_bytes() expected bytes的错误。更关键的是,Tranzila需要的是一个完整的JSON数组的url编码值,而不是多个零散JSON字符串的集合。

修正后的代码实现

把购物车数据的构建和编码逻辑改成这样:

def cart_detail(request, total=0, counter=0, cart_items=None):
    json_purchase_data = None
    cart_data = []
    try:
        cart = Cart.objects.get(cart_id=_cart_id(request))
        cart_items = CartItem.objects.filter(cart=cart, active=True)
        for cart_item in cart_items:
            # 计算总价和商品数量
            total += (cart_item.product.price * cart_item.quantity)
            counter += cart_item.quantity
            # 直接将商品信息以Python字典形式加入列表,不要提前转JSON
            cart_data.append({
                "product_name": str(cart_item.product),
                "product_quantity": int(cart_item.quantity),
                "product_price": int(cart_item.product.price)
            })
        # 把整个购物车列表转成一个完整的JSON字符串
        json_cart_str = json.dumps(cart_data)
        # 对这个JSON字符串进行url编码
        json_purchase_data = quote(json_cart_str)
        print(json_purchase_data)  # 可以打印出来确认格式是否正确
    except ObjectDoesNotExist:
        pass
    # 后续的thtk、dc_disable、form逻辑保持不变
    thtk = create_thtk(total).split("=")[1]
    dc_disable = create_dc_disable()
    if request.method == 'POST':
        form = UserData(request.POST)
    else:
        form = UserData()
    context = {
        'cart_items': cart_items,
        'total': total,
        'counter': counter,
        'terminal_name': terminal_name,
        'thtk': thtk,
        'dc_disable': dc_disable,
        'form': form,
        'json_purchase_data': json_purchase_data
    }
    return render(request, 'cart/cart.html', context)

关键修正点说明

  • 构建Python原生数据结构:先把所有商品信息以字典形式存入cart_data列表,这是标准的Python列表,而非零散的JSON字符串。
  • 整体转JSON:用json.dumps()把整个cart_data列表转成一个完整的JSON数组字符串,格式类似[{"product_name": "XXX", ...}, {...}]。
  • 正确编码:把这个完整的JSON字符串传给quote(),此时quote()会正确处理字符串(自动转换为字节进行编码),得到符合要求的rawurlencoded格式。

额外注意事项

  • 如果你商品价格是元为单位的浮点数(比如9.99元),直接转int会丢失小数部分,建议乘以100转成分(比如int(cart_item.product.price * 100)),避免金额误差,具体要匹配Tranzila的金额单位要求。
  • 可以打印json_purchase_data确认最终编码后的格式,确保是一个url安全的字符串,没有特殊字符未被转义。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:07:41