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

Django电商网站composed_cart报错:Decimal类型无法JSON序列化

解决Django中composed_cart的Decimal JSON序列化错误

嘿,我之前做Django电商项目时也踩过这个一模一样的坑!这个错误的核心原因很明确:Django默认用JSON序列化session中的数据,但Python的Decimal类型并不是JSON原生支持的数据类型——你的cart应该已经做了对应的类型处理,而composed_cart漏掉了这一步,才会在展示时触发序列化报错。

下面给你几个实用的解决方案:

方案1:存储时将Decimal转为字符串(最直接快速)

这是最容易落地的修复方式,在向composed_cart添加商品时,把价格这类Decimal字段转成字符串再存入session:

# 示例:composed_cart.py中的添加逻辑修改
from decimal import Decimal
from .models import Product

def add_to_composed_cart(request, product_id, quantity):
    composed_cart = request.session.get('composed_cart', {})
    product = Product.objects.get(id=product_id)
    
    # 关键:把Decimal类型的price转成字符串
    cart_item = {
        'product_id': product.id,
        'price': str(product.price),
        'name': product.name,
        'quantity': quantity
    }
    composed_cart[str(product_id)] = cart_item
    request.session['composed_cart'] = composed_cart

之后在展示购物车的视图里,再把字符串转回Decimal来计算总价:

# 购物车展示视图中的处理
from decimal import Decimal

def show_composed_cart(request):
    composed_cart = request.session.get('composed_cart', {})
    total = Decimal('0.00')
    for item in composed_cart.values():
        # 将字符串转回Decimal以保证计算精度
        item['price'] = Decimal(item['price'])
        item['subtotal'] = item['price'] * item['quantity']
        total += item['subtotal']
    return render(request, 'composed_cart.html', {'cart': composed_cart, 'total': total})

方案2:自定义Session序列化器(全局统一处理)

如果你不想每次都手动转类型,可以自定义一个能处理Decimal的JSON编码器,让Django的session自动兼容Decimal类型:

  1. 在项目的utils.py中创建自定义编码器:
from django.core.serializers.json import DjangoJSONEncoder
from decimal import Decimal

class DecimalJSONEncoder(DjangoJSONEncoder):
    def default(self, obj):
        if isinstance(obj, Decimal):
            # 转成字符串保留精度(不建议转float,会丢失精度)
            return str(obj)
        return super().default(obj)
  1. 在settings.py中配置全局session序列化器:
SESSION_SERIALIZER = 'your_project_name.utils.DecimalJSONEncoder'

这样所有存入session的Decimal都会被自动转成字符串,取出来时按需转回Decimal即可,不用每个模块都重复处理。

额外建议:对比cart的实现找差异

既然cart能正常工作,你可以仔细对比cart.py和composed_cart.py的代码,看看cart是怎么处理价格这类Decimal字段的——大概率它已经做了类型转换或者用了其他兼容JSON的存储方式,直接照搬这个逻辑到composed_cart里也能快速解决问题。

别着急,电商购物车涉及的细节确实不少,解决这个问题之后,你对Django的session机制和数据类型序列化的理解会更深入的!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:31:51