pythondjango

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


Solution

  • 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


    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


    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


    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.