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
相关产品推荐
相关产品推荐

