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

Django使用Session实现购物车时如何在模板中显示Variant规格的价格

Django Session购物车规格价格展示故障修复方案

核心调整是将购物车的存储维度从商品(Product)改为商品规格(Variants),每个购物车条目对应一个独立的规格实例,而非笼统的商品实例

1. 首先调整加购表单,增加规格参数接收

修改CartAddForm,新增尺寸、颜色选择字段,用于接收用户选中的规格:

class CartAddForm(forms.Form):
    quantity = forms.IntegerField(min_value=1)
    size = forms.ModelChoiceField(queryset=Size.objects.all())
    color = forms.ModelChoiceField(queryset=Color.objects.all())
    # 实际生产环境可根据当前商品动态过滤可选规格,避免无效提交

2. 重写Cart购物车核心逻辑

调整存储结构以Variant ID为key,同时修改迭代逻辑绑定规格实例:

CART_SESSION_ID = 'cart'

class Cart:
    def __init__(self, request):
        self.session = request.session
        cart = self.session.get(CART_SESSION_ID)
        if not cart:
            cart = self.session[CART_SESSION_ID] = {}
        self.cart = cart

    def __iter__(self):
        # 拿取所有购物车中的规格ID
        variant_ids = self.cart.keys()
        # 关联查询规格及对应商品信息,减少数据库查询次数
        variants = Variants.objects.filter(id__in=variant_ids).select_related('product')
        cart = self.cart.copy()
        for variant in variants:
            cart[str(variant.id)]['variant'] = variant
            cart[str(variant.id)]['product'] = variant.product
            # 预计算单条规格的购物车小计
            cart[str(variant.id)]['subtotal'] = variant.price * cart[str(variant.id)]['quantity']
        # 迭代返回每个购物车条目
        for item in cart.values():
            yield item
            
    def add(self, variant, quantity):
        variant_id = str(variant.id)
        if variant_id not in self.cart:
            # 存储当前规格的价格、数量
            self.cart[variant_id] = {'quantity': 0, 'price': str(variant.price)}
        self.cart[variant_id]['quantity'] += quantity
        self.save()

    def save(self):
        self.session.modified = True

3. 修改加购视图逻辑

根据表单提交的规格参数查询对应Variants实例,传给购物车add方法:

# 加入购物车
def cart_add(request, product_id):
    cart = Cart(request)
    product = get_object_or_404(Product, id=product_id)
    form = CartAddForm(request.POST)
    if form.is_valid():
        cd = form.cleaned_data
        # 匹配用户选中的规格实例
        variant = get_object_or_404(Variants, 
            product=product,
            size_id=cd['size'],
            color_id=cd['color']
        )
        cart.add(variant=variant, quantity=cd['quantity'])
    return redirect('cart:details')

4. 调整模板输出

直接从绑定的variant实例中拿取对应规格的价格即可:

{% for c in cart %}
    <tr>     
        <td>{{ c.product.name }}</td>
        <td>颜色:{{ c.variant.color.name }} | 尺寸:{{ c.variant.size.name }}</td>
        <td>{{ c.variant.price }}</td>
        <td>小计:{{ c.subtotal }}</td>
    </tr>
{% endfor %}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 01:27:02