add main_image field to product serializers and update components to use it

This commit is contained in:
Parsa Nazer
2026-01-06 14:10:48 +03:30
parent 0d1cd08521
commit 2fe7fa0005
4 changed files with 26 additions and 7 deletions
+22 -2
View File
@@ -67,9 +67,12 @@ class ProductVariantSerialzier(serializers.ModelSerializer):
cart_quantity = serializers.SerializerMethodField() cart_quantity = serializers.SerializerMethodField()
price = serializers.SerializerMethodField() price = serializers.SerializerMethodField()
price_after_discount = serializers.SerializerMethodField() price_after_discount = serializers.SerializerMethodField()
special_discount_amount = serializers.SerializerMethodField()
special_discount_link = serializers.SerializerMethodField()
class Meta: class Meta:
model = ProductVariant model = ProductVariant
exclude = ('min_price', 'sell', 'currency', 'product', 'input_price', 'price_in_dollor') exclude = ('min_price', 'sell', 'currency', 'product', 'input_price', 'price_in_dollor', 'profit', 'special_discount_percent')
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
@@ -77,6 +80,16 @@ class ProductVariantSerialzier(serializers.ModelSerializer):
if view_type == 'list': if view_type == 'list':
self.fields.pop('in_pack_items', None) self.fields.pop('in_pack_items', None)
def get_special_discount_amount(self, obj):
if obj.special_discount_percent:
special_discount_amount = obj.profit * (obj.special_discount_percent / 100)
return f'{special_discount_amount:,.0f} تومانءءء'
else:
return None
def get_special_discount_link(self, obj):
return 'https://'
def get_price_after_discount(self, obj): def get_price_after_discount(self, obj):
return f'{obj.price_after_discount:,.0f} تومانءءء' return f'{obj.price_after_discount:,.0f} تومانءءء'
@@ -139,6 +152,7 @@ class DynamicProductSerializer(serializers.ModelSerializer):
best_deal_price_before_discount = serializers.SerializerMethodField() best_deal_price_before_discount = serializers.SerializerMethodField()
best_deal_price_after_discount = serializers.SerializerMethodField() best_deal_price_after_discount = serializers.SerializerMethodField()
best_deal_discount = serializers.SerializerMethodField() best_deal_discount = serializers.SerializerMethodField()
main_image = serializers.SerializerMethodField()
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
view_type = self.context.get('view_type', 'all') view_type = self.context.get('view_type', 'all')
@@ -154,11 +168,17 @@ class DynamicProductSerializer(serializers.ModelSerializer):
model = ProductModel model = ProductModel
fields = "__all__" fields = "__all__"
view_type = { view_type = {
'list': ['id', 'name', 'rating', 'slug', 'category', 'variants', 'colors', 'image', 'best_deal_price_before_discount', 'best_deal_price_after_discount', 'best_deal_discount', ], 'list': ['id', 'name', 'rating', 'slug', 'category', 'colors', 'image', 'best_deal_price_before_discount', 'best_deal_price_after_discount', 'best_deal_discount', 'main_image'],
'slider': ['id', 'name', 'rating', 'slug', 'category', 'variants', 'colors', 'image', 'best_deal_price_before_discount', 'best_deal_price_after_discount', 'best_deal_discount', ], 'slider': ['id', 'name', 'rating', 'slug', 'category', 'variants', 'colors', 'image', 'best_deal_price_before_discount', 'best_deal_price_after_discount', 'best_deal_discount', ],
'instance': ['id', 'name', 'description', 'rating', 'slug', 'meta_description', 'meta_keywords', 'meta_rating', 'category', 'related_products', 'in_pack_items', 'variants', 'colors', 'added_to_favorites', 'image'], 'instance': ['id', 'name', 'description', 'rating', 'slug', 'meta_description', 'meta_keywords', 'meta_rating', 'category', 'related_products', 'in_pack_items', 'variants', 'colors', 'added_to_favorites', 'image'],
'chat': ['id', 'name', 'description', 'variants', 'image'] 'chat': ['id', 'name', 'description', 'variants', 'image']
} }
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
def get_best_deal_price_before_discount(self, obj): def get_best_deal_price_before_discount(self, obj):
best_deal = obj.get_best_deal_variant() best_deal = obj.get_best_deal_variant()
if best_deal: if best_deal:
+1 -1
View File
@@ -45,7 +45,7 @@ withDefaults(defineProps<Props>(), {
:id="product.id" :id="product.id"
:slug="product.slug" :slug="product.slug"
:title="product.name" :title="product.name"
:picture="product.image ?? product.variants[0].images[0].image" :picture="product.main_image"
:colors="product.colors" :colors="product.colors"
:price="product.best_deal_price_before_discount" :price="product.best_deal_price_before_discount"
:rate="product.rating" :rate="product.rating"
@@ -91,7 +91,7 @@ const onSwiper = (swiper: SwiperClass) => {
:id="product.id" :id="product.id"
:slug="product.slug" :slug="product.slug"
:title="product.name" :title="product.name"
:picture="product.image ?? product.variants[0].images[0].image" :picture="product.main_image"
:colors="product.colors" :colors="product.colors"
:rate="product.rating" :rate="product.rating"
:dark-layer="true" :dark-layer="true"
+2 -3
View File
@@ -106,7 +106,7 @@ declare global {
category: SubCategory; category: SubCategory;
colors: string[]; colors: string[];
added_to_favorites: boolean; added_to_favorites: boolean;
image: string | null; main_image: string;
best_deal_price_before_discount: string; best_deal_price_before_discount: string;
best_deal_price_after_discount: string; best_deal_price_after_discount: string;
best_deal_discount: number; best_deal_discount: number;
@@ -115,13 +115,12 @@ declare global {
type ProductListItem = Pick< type ProductListItem = Pick<
Product, Product,
| "id" | "id"
| "variants"
| "name" | "name"
| "rating" | "rating"
| "slug" | "slug"
| "category" | "category"
| "colors" | "colors"
| "image" | "main_image"
| "best_deal_discount" | "best_deal_discount"
| "best_deal_price_after_discount" | "best_deal_price_after_discount"
| "best_deal_price_before_discount" | "best_deal_price_before_discount"