Django: Как динамически обновлять количество товара на складе при выборе его разновидности?
Я работаю над проектом электронной коммерции, где продукт имеет несколько вариаций (например, разные цвета, размеры и т. д.), и каждая вариация имеет свой собственный запас. Когда пользователь выбирает вариацию, я хочу динамически обновлять отображаемый запас, но это работает неправильно.
Вот моя модель ProductStock:
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
В моем шаблоне HTML я отображаю варианты в виде радиокнопок:
{% 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>
И моя JavaScript-функция для динамического обновления запасов:
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 = "-";
}
}
Выпуск
- Складской запас не обновляется при выборе вариации.
- Иногда он показывает неправильные значения или вообще не меняется.
Проблема возникает из-за того, что данные о запасах неправильно передаются в JavaScript, а функция updateStock
не имеет доступа к данным о запасах в реальном времени.
Шаг 1: Передайте данные о запасах в формате JSON в представлении Django
В моем представлении Django мне нужно получить данные о продукте на складе, преобразовать их в объект JSON и отправить в шаблон.
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
, чтобы получить все запасы, связанные с продуктом. - Я преобразую данные о запасах в формат JSON (
size_stock_data
) для передачи в JavaScript. - Это гарантирует, что каждый вариант содержит правильные данные о запасах при доступе к ним в интерфейсе.
Шаг 2: Вставьте биржевые данные в JavaScript
В моем HTML-шаблоне я включаю это в тег <script>
:
<script>
var stockData = JSON.parse('{{ size_stock_data|safe }}');
</script>
Объяснение
- Это делает данные о запасах доступными в JavaScript.
stockData
теперь содержит словарь, в котором идентификатор каждой разновидности соответствует информации о ее запасе.
Шаг 3: Обновите JavaScript, чтобы использовать правильные данные
Измените мою функцию updateStock
:
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";
}
}
Объяснение
- Когда пользователь нажимает на вариант, вызывается эта функция.
- Он извлекает данные о запасах для выбранного варианта.
- Это динамически обновляет отображение запасов.
Окончательный результат
Запасы обновляются динамически при выборе варианта.
Нет необходимости обновлять страницу для отображения обновленного ассортимента.
Отображаются правильные значения для каждого варианта.