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 ProductStock model 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.
  • stockData now 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.

Back to Top