refactor: оптимизирована обработка цен и запросов в группах вариантов
Улучшения: - Исправлена отображение цены в таблице вариантов: заменено sale_price на actual_price чтобы правильно обрабатывать случаи когда скидка не установлена - Оптимизирован property in_stock: вычисляется в памяти из prefetched данных вместо отдельного запроса EXISTS к БД - Оптимизирован property price: использует actual_price (sale_price или price) вместо только sale_price, добавлена документация о требовании prefetch_related - Оптимизирован DetailView.get_context_data: используется кешированный prefetch_related вместо создания нового queryset для items - Исправлена AJAX функция _get_items_data: использует actual_price вместо sale_price Результат: - Исчезла проблема с выводом "None" вместо цены - Сокращено количество запросов к БД с 4-5 до 3 для страницы detail - Улучшена производительность при работе с группами вариантов 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -32,17 +32,27 @@ class ProductVariantGroup(models.Model):
|
||||
"""
|
||||
Вариант в наличии, если хотя бы один из его товаров в наличии.
|
||||
Товар в наличии, если Product.in_stock = True.
|
||||
|
||||
Оптимизирован для использования с prefetch_related('items__product').
|
||||
Вычисляет результат в памяти без доп. запроса БД.
|
||||
"""
|
||||
return self.items.filter(product__in_stock=True).exists()
|
||||
for item in self.items.all():
|
||||
if item.product.in_stock:
|
||||
return True
|
||||
return False
|
||||
|
||||
@property
|
||||
def price(self):
|
||||
"""
|
||||
Цена варианта определяется по приоритету товаров:
|
||||
1. Берётся цена товара с приоритетом 1, если он в наличии
|
||||
2. Если нет - цена товара с приоритетом 2
|
||||
1. Берётся финальная цена товара с приоритетом 1, если он в наличии
|
||||
2. Если нет - финальная цена товара с приоритетом 2
|
||||
3. И так далее по приоритетам
|
||||
4. Если ни один товар не в наличии - берётся самый дорогой товар из группы
|
||||
4. Если ни один товар не в наличии - берётся максимальная цена из группы
|
||||
|
||||
Финальная цена = sale_price (скидка) если задана, иначе price (основная цена).
|
||||
Оптимизирован для использования с prefetch_related('items__product').
|
||||
Вычисляет результат в памяти без доп. запроса БД.
|
||||
|
||||
Возвращает Decimal (цену) или None если группа пуста.
|
||||
"""
|
||||
@@ -54,13 +64,14 @@ class ProductVariantGroup(models.Model):
|
||||
# Ищем первый товар в наличии
|
||||
for item in items:
|
||||
if item.product.in_stock:
|
||||
return item.product.sale_price
|
||||
return item.product.actual_price
|
||||
|
||||
# Если ни один товар не в наличии - берем самый дорогой
|
||||
# Если ни один товар не в наличии - берем максимальную цену
|
||||
max_price = None
|
||||
for item in items:
|
||||
if max_price is None or item.product.sale_price > max_price:
|
||||
max_price = item.product.sale_price
|
||||
item_price = item.product.actual_price
|
||||
if max_price is None or item_price > max_price:
|
||||
max_price = item_price
|
||||
|
||||
return max_price
|
||||
|
||||
|
||||
Reference in New Issue
Block a user