Django: How to dynamically update stock quantity when selecting a product variation?
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 = "-";
}
}
Issue
- The stock does not update when selecting a variation.
- Sometimes, it shows incorrect values or does not change at all.
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.
Step 1: Pass Stock Data as JSON in Django View
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)
Explanation
- I query the
ProductStockmodel to get all stocks related to the product. - I convert the stock data into a JSON format (
size_stock_data) to be passed to JavaScript. - This ensures that each variation has the correct stock data when accessed in the frontend.
Step 2: Embed Stock Data in JavaScript
In my HTML template, I include this inside the <script> tag:
<script>
var stockData = JSON.parse('{{ size_stock_data|safe }}');
</script>
Explanation
- This makes the stock data available in JavaScript.
stockDatanow contains a dictionary where each variation ID maps to its stock information.
Step 3: Update JavaScript to Use the Correct Data
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";
}
}
Explanation
- When a user clicks on a variation, this function is called.
- It fetches the stock data for the selected variation.
- It updates the stock display dynamically.
Final Outcome
Stock updates dynamically when a variation is selected.
No need for page refresh to show updated stock.
Correct values are displayed for each variation.