I am working on an e-commerce project where a product has multiple variations (like different colors, sizes, etc.), and each variation has its own stock. When a user selects a variation, I want to update the displayed stock dynamically, but it is not working correctly.
Here’s my ProductStock model:
class ProductStock(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name="stocks")
variation = models.ForeignKey(Variation, on_delete=models.CASCADE, blank=True, null=True)
uploaded_stock_quantity = models.PositiveIntegerField(default=0)
stock_quantity = models.PositiveIntegerField(default=0)
reserved_stock = models.PositiveIntegerField(default=0) # For pending orders
def available_stock(self):
return self.stock_quantity - self.reserved_stock
In my HTML template, I display variations as radio buttons:
{% for v in variations %}
<div class="variation__radio">
<input type="radio" id="variation_{{ v.id }}" name="variation"
onclick="updateStock(this);" value="{{ v.id }}">
<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>
And my JavaScript function to update stock dynamically:
function updateStock(element) {
var variationId = element.value;
var stockData = JSON.parse('{{ size_stock_data|safe }}'); // Pass stock data
if (stockData[variationId]) {
document.getElementById("uploaded-stock").textContent = stockData[variationId].uploaded_stock_quantity;
document.getElementById("remaining-stock").textContent = stockData[variationId].stock_quantity;
} else {
document.getElementById("uploaded-stock").textContent = "-";
document.getElementById("remaining-stock").textContent = "-";
}
}
The issue occurs because the stock data is not being passed correctly to JavaScript, and the updateStock
function does not have access to real-time stock data.
In my Django view, I need to fetch the product stock, convert it to a JSON object, and send it to the template.
import json
def product_variant_detail_view(request, pid):
product = Product.objects.get(pid=pid)
product_stocks = ProductStock.objects.filter(product=product)
# Prepare stock data for JavaScript
size_stock_data = {
str(stock.variation.id): {
'stock_quantity': stock.stock_quantity,
'uploaded_stock_quantity': stock.uploaded_stock_quantity
}
for stock in product_stocks if stock.variation
}
context = {
"product": product,
"size_stock_data": json.dumps(size_stock_data), # Convert to JSON
}
return render(request, "core/product_variant_detail.html", context)
ProductStock
model to get all stocks related to the product.size_stock_data
) to be passed to JavaScript.In my HTML template, I include this inside the <script>
tag:
<script>
var stockData = JSON.parse('{{ size_stock_data|safe }}');
</script>
stockData
now contains a dictionary where each variation ID maps to its stock information.Modify my updateStock
function:
function updateStock(element) {
var variationId = element.value; // Get selected variation ID
if (stockData[variationId]) {
document.getElementById("uploaded-stock").textContent = stockData[variationId].uploaded_stock_quantity + " in stock";
document.getElementById("remaining-stock").textContent = stockData[variationId].stock_quantity + " left";
} else {
document.getElementById("uploaded-stock").textContent = "0 in stock";
document.getElementById("remaining-stock").textContent = "0 left";
}
}
Stock updates dynamically when a variation is selected.
No need for page refresh to show updated stock.
Correct values are displayed for each variation.