optimze home page and product page
This commit is contained in:
@@ -122,12 +122,11 @@ class SubCategorySerializer(serializers.ModelSerializer):
|
||||
'meta_description', 'product_count', 'parent', 'image']
|
||||
|
||||
def get_product_count(self, obj):
|
||||
# Use annotated product_count if available (from optimized query)
|
||||
# Otherwise fall back to counting (for backward compatibility)
|
||||
return getattr(obj, 'product_count', obj.products.count())
|
||||
# Use annotated product_count from database annotation
|
||||
return getattr(obj, 'product_count', 0)
|
||||
|
||||
def get_parent(self, obj):
|
||||
return obj.parent.name
|
||||
return obj.parent.name if obj.parent else None
|
||||
|
||||
|
||||
class UnitCategorySerializer(serializers.ModelSerializer):
|
||||
@@ -159,6 +158,7 @@ class DynamicProductSerializer(serializers.ModelSerializer):
|
||||
main_image = serializers.SerializerMethodField()
|
||||
customer_pickup_title = serializers.SerializerMethodField()
|
||||
customer_pickup_description = serializers.SerializerMethodField()
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
view_type = self.context.get('view_type', 'all')
|
||||
@@ -180,31 +180,48 @@ class DynamicProductSerializer(serializers.ModelSerializer):
|
||||
'chat': ['id', 'name', 'description', 'variants', 'image']
|
||||
}
|
||||
|
||||
def _get_best_deal_variant(self, obj):
|
||||
"""Get best deal variant from prefetched variants (pre-ordered by discount/price)"""
|
||||
if not hasattr(self, '_best_deal_cache'):
|
||||
self._best_deal_cache = {}
|
||||
|
||||
if obj.id not in self._best_deal_cache:
|
||||
# Get first from prefetched variants (already ordered by discount desc, price asc)
|
||||
variants = list(obj.variants.all())
|
||||
self._best_deal_cache[obj.id] = variants[0] if variants else None
|
||||
|
||||
return self._best_deal_cache[obj.id]
|
||||
|
||||
def get_main_image(self, obj):
|
||||
if obj.image:
|
||||
return obj.image.url
|
||||
return obj.variants.first().images.first().image.url if obj.variants.exists() and obj.variants.first().images.exists() else None
|
||||
# Use prefetched variants
|
||||
variants = list(obj.variants.all())
|
||||
if variants:
|
||||
images = list(variants[0].images.all())
|
||||
if images:
|
||||
return images[0].image.url
|
||||
return None
|
||||
|
||||
def get_best_deal_price_before_discount(self, obj):
|
||||
best_deal = obj.get_best_deal_variant()
|
||||
best_deal = self._get_best_deal_variant(obj)
|
||||
if best_deal:
|
||||
return f'{best_deal.price:,.0f} تومانءءء'
|
||||
return 0
|
||||
|
||||
def get_best_deal_price_after_discount(self, obj):
|
||||
best_deal = obj.get_best_deal_variant()
|
||||
best_deal = self._get_best_deal_variant(obj)
|
||||
if best_deal:
|
||||
price_after_discount = best_deal.price_after_discount
|
||||
return f'{price_after_discount:,.0f} تومانءءء'
|
||||
return 0
|
||||
|
||||
def get_best_deal_discount(self, obj):
|
||||
best_deal = obj.get_best_deal_variant()
|
||||
best_deal = self._get_best_deal_variant(obj)
|
||||
if best_deal:
|
||||
return best_deal.discount
|
||||
return 0
|
||||
|
||||
|
||||
def get_customer_pickup_title(self, obj):
|
||||
if obj.shop:
|
||||
return obj.shop.customer_pickup_title
|
||||
@@ -219,7 +236,7 @@ class DynamicProductSerializer(serializers.ModelSerializer):
|
||||
from account.models import UserFavorites
|
||||
request = self.context.get('request')
|
||||
if not request or not request.user.is_authenticated:
|
||||
return False # not logged in users haven't added anything
|
||||
return False
|
||||
|
||||
# Use exists() with filter instead of fetching all products
|
||||
return UserFavorites.objects.filter(user=request.user, products=obj).exists()
|
||||
@@ -230,23 +247,24 @@ class DynamicProductSerializer(serializers.ModelSerializer):
|
||||
varients = obj.variants.filter(slider_category__isnull=False)
|
||||
else:
|
||||
varients = obj.variants.all()
|
||||
colors = set(varient.color for varient in varients)
|
||||
return ProductVariantSerialzier(instance=varients, many=True, context=self.context).data
|
||||
|
||||
def get_colors(self, obj):
|
||||
# Use values_list to get only color field, reducing data transfer
|
||||
colors = obj.variants.values_list('color', flat=True).distinct()
|
||||
return list(filter(None, colors)) # Filter out None values
|
||||
# Get colors from prefetched variants efficiently
|
||||
variants = list(obj.variants.all())
|
||||
colors = set()
|
||||
for variant in variants:
|
||||
if variant.color:
|
||||
colors.add(variant.color)
|
||||
return list(colors)
|
||||
|
||||
def get_is_new(self, obj):
|
||||
return timezone.now() < obj.created_at + timedelta(days=7)
|
||||
|
||||
def get_related_products(self, obj):
|
||||
if obj.related_products.all().count() >= 5:
|
||||
# Limit to 10 related products
|
||||
related_products = obj.related_products.all()[:10]
|
||||
else:
|
||||
# Limit category products and exclude current product
|
||||
related_products = obj.category.products.exclude(id=obj.id)[:10]
|
||||
|
||||
serializer = DynamicProductSerializer(
|
||||
|
||||
Reference in New Issue
Block a user