Django电商项目:选择商品变体时如何正确动态更新库存数量?
Django电商项目:选择商品变体时如何正确动态更新库存数量?
看起来你遇到了变体切换时库存不更新的问题,我来帮你一步步排查和解决~
首先,我们从最可能的问题点入手:
1. 后端传递的库存数据是否正确?
你在JS里用了JSON.parse('{{ size_stock_data|safe }}')获取库存数据,但如果后端没有正确生成这个JSON,JS就找不到对应变体的库存信息,自然不会更新。
你需要在视图里把库存数据整理成以变体ID为键的字典,再转成JSON字符串传到模板:
import json from django.views.generic import DetailView from .models import Product class ProductDetailView(DetailView): model = Product template_name = "product_detail.html" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) product = self.object # 整理库存数据:键是变体ID的字符串,值是库存详情 size_stock_data = {} for stock in product.stocks.all(): if stock.variation: size_stock_data[str(stock.variation.id)] = { "uploaded_stock_quantity": stock.uploaded_stock_quantity, "stock_quantity": stock.stock_quantity, "available_stock": stock.available_stock() # 把可用库存也带上,用户更关心这个 } # 转成JSON字符串传给模板 context["size_stock_data"] = json.dumps(size_stock_data) context["variations"] = product.variations.all() # 确保变体数据正确传递 return context
2. 修复JS逻辑的小问题
你的JS里可能存在类型不匹配的问题:radio的value是字符串类型的ID,而如果stockData的键是数字,就会找不到对应值。另外,页面加载时默认选中的变体没有触发更新,导致初始显示“-”。
修改后的JS代码:
function updateStock(element) { // 把变体ID转成数字,确保和stockData的键类型匹配 const variationId = parseInt(element.value); // 解析后端传递的JSON数据 const stockData = JSON.parse('{{ size_stock_data|safe }}'); if (stockData[variationId]) { document.getElementById("uploaded-stock").textContent = stockData[variationId].uploaded_stock_quantity; // 建议显示可用库存(总库存-预留库存),这才是用户能购买的数量 document.getElementById("remaining-stock").textContent = stockData[variationId].available_stock; } else { document.getElementById("uploaded-stock").textContent = "-"; document.getElementById("remaining-stock").textContent = "-"; } } // 页面加载完成后,自动触发默认选中变体的库存更新 document.addEventListener('DOMContentLoaded', function() { const defaultVariation = document.querySelector('input[name="variation"]:checked'); if (defaultVariation) { updateStock(defaultVariation); } });
3. 模板里的小优化
给第一个变体加上默认选中,确保页面加载时就有库存显示:
{% for v in variations %} <div class="variation__radio"> <input type="radio" id="variation_{{ v.id }}" name="variation" onclick="updateStock(this);" value="{{ v.id }}" {% if forloop.first %}checked{% endif %}> <label for="variation_{{ v.id }}">{{ v.name }}</label> </div> {% endfor %} <div class="stock-info"> <span id="uploaded-stock">-</span> in stock, <span id="remaining-stock">-</span> left </div>
4. 排查小技巧
如果还是没生效,打开浏览器的**开发者工具(F12)**看Console面板:
- 有没有JSON解析错误?说明后端传递的
size_stock_data格式不对 - 有没有“找不到元素”的错误?检查元素ID是否拼写正确
- 点击变体时,打印
variationId和stockData,看看是否能找到对应的数据
备注:内容来源于stack exchange,提问作者Google User
相关产品推荐
相关产品推荐

