From 17fcbea5db96c1f924461df530f77abb3dd50a99 Mon Sep 17 00:00:00 2001 From: Parsa Nazer Date: Mon, 10 Feb 2025 18:18:19 +0330 Subject: [PATCH 1/7] max price exclude --- backend/product/serializers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/product/serializers.py b/backend/product/serializers.py index 11fc5fc..4907698 100644 --- a/backend/product/serializers.py +++ b/backend/product/serializers.py @@ -35,7 +35,7 @@ class ProductVariantSerialzier(serializers.ModelSerializer): price = serializers.SerializerMethodField() class Meta: model = ProductVariant - exclude = ('min_price', 'sell', 'currency', 'product') + exclude = ('min_price', 'max_price','sell', 'currency', 'product') def get_price(self, obj): dollor_price = self.context.get('dollor_price') From 8eaeab9889d7540101d8885094a9f6fc22edbb7d Mon Sep 17 00:00:00 2001 From: Parsa Nazer Date: Tue, 11 Feb 2025 21:40:50 +0330 Subject: [PATCH 2/7] update account fields --- .../0006_user_brith_day_user_gender.py | 25 +++++++++++++++++++ .../0007_rename_brith_day_user_birth_day.py | 18 +++++++++++++ backend/account/models.py | 6 +++++ backend/account/serializers.py | 2 +- 4 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 backend/account/migrations/0006_user_brith_day_user_gender.py create mode 100644 backend/account/migrations/0007_rename_brith_day_user_birth_day.py diff --git a/backend/account/migrations/0006_user_brith_day_user_gender.py b/backend/account/migrations/0006_user_brith_day_user_gender.py new file mode 100644 index 0000000..e7d61c3 --- /dev/null +++ b/backend/account/migrations/0006_user_brith_day_user_gender.py @@ -0,0 +1,25 @@ +# Generated by Django 5.1.2 on 2025-02-11 17:14 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('account', '0005_alter_useraddressmodel_options_alter_user_is_active_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='user', + name='brith_day', + field=models.DateField(default='2024-10-09'), + preserve_default=False, + ), + migrations.AddField( + model_name='user', + name='gender', + field=models.CharField(choices=[('male', 'مرد'), ('female', 'زن')], default='male', max_length=20, verbose_name='جنسیت'), + preserve_default=False, + ), + ] diff --git a/backend/account/migrations/0007_rename_brith_day_user_birth_day.py b/backend/account/migrations/0007_rename_brith_day_user_birth_day.py new file mode 100644 index 0000000..b6b8e74 --- /dev/null +++ b/backend/account/migrations/0007_rename_brith_day_user_birth_day.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.2 on 2025-02-11 18:10 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('account', '0006_user_brith_day_user_gender'), + ] + + operations = [ + migrations.RenameField( + model_name='user', + old_name='brith_day', + new_name='birth_day', + ), + ] diff --git a/backend/account/models.py b/backend/account/models.py index 74d4ad9..4ad25c6 100644 --- a/backend/account/models.py +++ b/backend/account/models.py @@ -41,6 +41,12 @@ class User(AbstractBaseUser, PermissionsMixin): profile_photo = models.ImageField(upload_to='profile_photos/', null=True, blank=True, verbose_name='عکس پروفایل') is_active = models.BooleanField(default=True, verbose_name='فعال بودن کاربر') is_staff = models.BooleanField(default=False, verbose_name='کارمند') + gender_option = ( + ('male', 'مرد'), + ('female', 'زن') + ) + gender = models.CharField(choices=gender_option, max_length=20, verbose_name='جنسیت') + birth_day = models.DateField() date_joined = models.DateTimeField(auto_now_add=True, verbose_name='تاریخ ثبتنام') otp_hash = models.CharField(max_length=64, null=True, blank=True, verbose_name='کد یک بار مصرف') otp_expiry = models.DateTimeField(null=True, blank=True, verbose_name='تاریخ تمام شدن کد یک بار مصرف') diff --git a/backend/account/serializers.py b/backend/account/serializers.py index dae6e9e..7b6ff1a 100644 --- a/backend/account/serializers.py +++ b/backend/account/serializers.py @@ -10,7 +10,7 @@ class CustomTokenObtainPairSerializer(TokenObtainPairSerializer): class ProfileSerializer(serializers.ModelSerializer): class Meta: model = User - fields = ['first_name', 'last_name', 'email', 'profile_photo', 'phone'] + fields = ['first_name', 'last_name', 'email', 'profile_photo', 'phone', 'gender', 'birth_day'] read_only_fields = ("phone",) From da111d0148bbc545ef21b0a8a9876198d842a9fb Mon Sep 17 00:00:00 2001 From: Parsa Nazer Date: Tue, 11 Feb 2025 21:52:03 +0330 Subject: [PATCH 3/7] account changes --- backend/account/admin.py | 4 ++-- .../0008_rename_birth_day_user_birth_date.py | 18 ++++++++++++++++++ backend/account/models.py | 2 +- backend/account/serializers.py | 2 +- 4 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 backend/account/migrations/0008_rename_birth_day_user_birth_date.py diff --git a/backend/account/admin.py b/backend/account/admin.py index 3e81445..f0214ab 100644 --- a/backend/account/admin.py +++ b/backend/account/admin.py @@ -30,11 +30,11 @@ class UserAdmin(BaseUserAdmin, ModelAdmin, ImportExportModelAdmin): list_display = ['full_name_display', 'phone', 'email', 'is_superuser', ] # readonly_fields = ['phone', 'email', 'otp_expiry', 'otp_hash', 'date_joined', 'profile_photo'] - exclude = ('otp_hash', 'otp_expiry', 'is_active', 'is_staff', 'password', 'last_login') + exclude = ('otp_hash', 'otp_expiry', 'is_active', 'is_staff', 'password', 'last_login', 'gender', 'birth_date') import_form_class = ImportForm export_form_class = ExportForm fieldsets = ( - ('اطلاعات شخصی', {'fields': ('first_name', 'last_name', 'profile_photo', 'password'),}), + ('اطلاعات شخصی', {'fields': ('first_name', 'last_name', 'profile_photo', 'password', 'gender', 'birth_date'),}), ('اطلاعات ارتباطی', {'fields': ('phone', 'email'),}), ) empty_value_display = 'ثبت نشده' diff --git a/backend/account/migrations/0008_rename_birth_day_user_birth_date.py b/backend/account/migrations/0008_rename_birth_day_user_birth_date.py new file mode 100644 index 0000000..b4a4d46 --- /dev/null +++ b/backend/account/migrations/0008_rename_birth_day_user_birth_date.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.2 on 2025-02-11 18:21 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('account', '0007_rename_brith_day_user_birth_day'), + ] + + operations = [ + migrations.RenameField( + model_name='user', + old_name='birth_day', + new_name='birth_date', + ), + ] diff --git a/backend/account/models.py b/backend/account/models.py index 4ad25c6..3b32635 100644 --- a/backend/account/models.py +++ b/backend/account/models.py @@ -46,7 +46,7 @@ class User(AbstractBaseUser, PermissionsMixin): ('female', 'زن') ) gender = models.CharField(choices=gender_option, max_length=20, verbose_name='جنسیت') - birth_day = models.DateField() + birth_date = models.DateField() date_joined = models.DateTimeField(auto_now_add=True, verbose_name='تاریخ ثبتنام') otp_hash = models.CharField(max_length=64, null=True, blank=True, verbose_name='کد یک بار مصرف') otp_expiry = models.DateTimeField(null=True, blank=True, verbose_name='تاریخ تمام شدن کد یک بار مصرف') diff --git a/backend/account/serializers.py b/backend/account/serializers.py index 7b6ff1a..0bb0e30 100644 --- a/backend/account/serializers.py +++ b/backend/account/serializers.py @@ -10,7 +10,7 @@ class CustomTokenObtainPairSerializer(TokenObtainPairSerializer): class ProfileSerializer(serializers.ModelSerializer): class Meta: model = User - fields = ['first_name', 'last_name', 'email', 'profile_photo', 'phone', 'gender', 'birth_day'] + fields = ['first_name', 'last_name', 'email', 'profile_photo', 'phone', 'gender', 'birth_date'] read_only_fields = ("phone",) From a206ad7079145dd4beafb432dfc7893930bd38c8 Mon Sep 17 00:00:00 2001 From: Parsa Nazer Date: Tue, 11 Feb 2025 21:57:58 +0330 Subject: [PATCH 4/7] comment change user form --- backend/account/admin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/account/admin.py b/backend/account/admin.py index f0214ab..94cd217 100644 --- a/backend/account/admin.py +++ b/backend/account/admin.py @@ -19,8 +19,8 @@ class UserAddressInLine(TabularInline): @admin.register(User) class UserAdmin(BaseUserAdmin, ModelAdmin, ImportExportModelAdmin): - form = UserChangeForm - add_form = UserCreationForm + # form = UserChangeForm + # add_form = UserCreationForm change_password_form = AdminPasswordChangeForm filter_horizontal = [] ordering = [] From 4234418e51b6b0888cacb359e9fec6b7f5ffd9a7 Mon Sep 17 00:00:00 2001 From: Parsa Nazer Date: Tue, 11 Feb 2025 22:14:28 +0330 Subject: [PATCH 5/7] account gender and birth date field update fix and add --- backend/account/admin.py | 8 ++++---- .../migrations/0009_alter_user_gender.py | 18 ++++++++++++++++++ backend/account/models.py | 4 ++-- 3 files changed, 24 insertions(+), 6 deletions(-) create mode 100644 backend/account/migrations/0009_alter_user_gender.py diff --git a/backend/account/admin.py b/backend/account/admin.py index 94cd217..07e62f7 100644 --- a/backend/account/admin.py +++ b/backend/account/admin.py @@ -19,18 +19,18 @@ class UserAddressInLine(TabularInline): @admin.register(User) class UserAdmin(BaseUserAdmin, ModelAdmin, ImportExportModelAdmin): - # form = UserChangeForm - # add_form = UserCreationForm + form = UserChangeForm + add_form = UserCreationForm change_password_form = AdminPasswordChangeForm filter_horizontal = [] ordering = [] inlines = [UserAddressInLine] list_filter = ['is_superuser'] search_fields = ['phone', 'first_name', 'last_name', 'email'] - list_display = ['full_name_display', 'phone', 'email', 'is_superuser', ] + list_display = ['full_name_display', 'phone', 'email', 'is_superuser', 'gender', 'birth_date'] # readonly_fields = ['phone', 'email', 'otp_expiry', 'otp_hash', 'date_joined', 'profile_photo'] - exclude = ('otp_hash', 'otp_expiry', 'is_active', 'is_staff', 'password', 'last_login', 'gender', 'birth_date') + exclude = ('otp_hash', 'otp_expiry', 'is_active', 'is_staff', 'password', 'last_login',) import_form_class = ImportForm export_form_class = ExportForm fieldsets = ( diff --git a/backend/account/migrations/0009_alter_user_gender.py b/backend/account/migrations/0009_alter_user_gender.py new file mode 100644 index 0000000..ed7e2b0 --- /dev/null +++ b/backend/account/migrations/0009_alter_user_gender.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.2 on 2025-02-11 18:42 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('account', '0008_rename_birth_day_user_birth_date'), + ] + + operations = [ + migrations.AlterField( + model_name='user', + name='gender', + field=models.CharField(choices=[('مرد', 'مرد'), ('زن', 'زن')], max_length=20, verbose_name='جنسیت'), + ), + ] diff --git a/backend/account/models.py b/backend/account/models.py index 3b32635..9038461 100644 --- a/backend/account/models.py +++ b/backend/account/models.py @@ -42,8 +42,8 @@ class User(AbstractBaseUser, PermissionsMixin): is_active = models.BooleanField(default=True, verbose_name='فعال بودن کاربر') is_staff = models.BooleanField(default=False, verbose_name='کارمند') gender_option = ( - ('male', 'مرد'), - ('female', 'زن') + ('مرد', 'مرد'), + ('زن', 'زن') ) gender = models.CharField(choices=gender_option, max_length=20, verbose_name='جنسیت') birth_date = models.DateField() From d8a588ca86249be26092c6c02aa3380c1d92cc75 Mon Sep 17 00:00:00 2001 From: Parsa Nazer Date: Tue, 11 Feb 2025 23:02:08 +0330 Subject: [PATCH 6/7] change color image video field and place it in product varient model --- backend/product/admin.py | 73 +++++++++++-------- ...ove_productmodel_in_pack_items_and_more.py | 22 ++++++ ...el_remove_attributevalue_color_and_more.py | 48 ++++++++++++ backend/product/models.py | 23 +++++- backend/product/serializers.py | 27 ++++++- 5 files changed, 157 insertions(+), 36 deletions(-) create mode 100644 backend/product/migrations/0021_remove_productmodel_in_pack_items_and_more.py create mode 100644 backend/product/migrations/0022_productimagemodel_remove_attributevalue_color_and_more.py diff --git a/backend/product/admin.py b/backend/product/admin.py index 96aaceb..334e46f 100644 --- a/backend/product/admin.py +++ b/backend/product/admin.py @@ -77,11 +77,24 @@ class AttributeValueAdmin(ModelAdmin, ImportExportModelAdmin): "widget": ArrayWidget, } } - def get_form(self, request, obj=None, change=False, **kwargs): - form = super().get_form(request, obj, change, **kwargs) - form.base_fields["color"].widget = UnfoldAdminColorInputWidget() - return form + # def get_form(self, request, obj=None, change=False, **kwargs): + # form = super().get_form(request, obj, change, **kwargs) + # form.base_fields["color"].widget = UnfoldAdminColorInputWidget() + # return form +@admin.register(ProductImageModel) +class ProductImagesAdmin(ModelAdmin): + import_form_class = ImportForm + export_form_class = ExportForm + search_fields = ['name'] + compressed_fields = True + warn_unsaved_form = True + + formfield_overrides = { + ArrayField: { + "widget": ArrayWidget, + } + } @@ -92,14 +105,14 @@ class ProductVariantInLine(StackedInline): show_change_link = True tab = True min_num = 1 - autocomplete_fields = ['attributes'] + autocomplete_fields = ['attributes', 'in_pack_items', 'images'] # search_fields = [''] - def get_form(self, request, obj=None, change=False, **kwargs): - form = super().get_form(request, obj, change, **kwargs) - form.base_fields["color"].widget = UnfoldAdminColorInputWidget() - return form + def formfield_for_dbfield(self, db_field, request, **kwargs): + if db_field.name == 'color': + kwargs['widget'] = UnfoldAdminColorInputWidget() + return super().formfield_for_dbfield(db_field, request, **kwargs) @@ -138,15 +151,15 @@ class ProductModelAdmin(ModelAdmin, ImportExportModelAdmin): readonly_fields = ('slug', ) search_fields = ['name', 'description', ] list_filter = ['show', 'category'] - autocomplete_fields = ['related_products', 'in_pack_items',] + autocomplete_fields = ['related_products', ] # compressed_fields = True warn_unsaved_form = True - list_display = ['display_image', 'display_price', 'view', 'show', 'rating', 'category', ] + list_display = ['display_price', 'view', 'show', 'rating', 'category', ] fieldsets = ( ('فیلد های اصلی', {'fields': ('name', 'description', 'category', 'related_products', 'show',), "classes": ["tab"],}), ('فیلد های سيو', {'fields': ('meta_description', 'meta_keywords', 'meta_rating', 'slug'), "classes": ["tab"],}), ('فیلد های مربوط به کاربر', {'fields': ('rating', 'view',), "classes": ["tab"],}), - ('فیلد های ایتم های پک', {'fields': ('in_pack_items', ), "classes": ["tab"],}) + # ('فیلد های ایتم های پک', {'fields': ('in_pack_items', ), "classes": ["tab"],}) ) formfield_overrides = { @@ -163,24 +176,24 @@ class ProductModelAdmin(ModelAdmin, ImportExportModelAdmin): return obj.get_toman_price() display_price.short_description = 'قیمت تومانی' - @display(description='محصول', header=True) - def display_image(self, instance): - if instance and instance.variants.first() and instance.variants.first().attributes.first(): - image = instance.variants.first().attributes.first().image.url if instance.variants.first().attributes.first().image else None - else: - image = None - return [ - instance.name, - None, - None, - { - "path": image, - "height": 30, - "width": 30, - "borderless": True, - # "squared": True, - }, - ] + # @display(description='محصول', header=True) + # def display_image(self, instance): + # if instance and instance.variants.first() and instance.variants.first().attributes.first(): + # image = instance.variants.first().attributes.first().image.url if instance.variants.first().attributes.first().image else None + # else: + # image = None + # return [ + # instance.name, + # None, + # None, + # { + # "path": image, + # "height": 30, + # "width": 30, + # "borderless": True, + # # "squared": True, + # }, + # ] # @display( # description=("نمایش در صفحه ی اصلی"), # label={ diff --git a/backend/product/migrations/0021_remove_productmodel_in_pack_items_and_more.py b/backend/product/migrations/0021_remove_productmodel_in_pack_items_and_more.py new file mode 100644 index 0000000..1e9785c --- /dev/null +++ b/backend/product/migrations/0021_remove_productmodel_in_pack_items_and_more.py @@ -0,0 +1,22 @@ +# Generated by Django 5.1.2 on 2025-02-11 17:44 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('product', '0020_productvariant_max_price_and_more'), + ] + + operations = [ + migrations.RemoveField( + model_name='productmodel', + name='in_pack_items', + ), + migrations.AddField( + model_name='productvariant', + name='in_pack_items', + field=models.ManyToManyField(blank=True, to='product.inpackitems', verbose_name='ایتم های داخل پک'), + ), + ] diff --git a/backend/product/migrations/0022_productimagemodel_remove_attributevalue_color_and_more.py b/backend/product/migrations/0022_productimagemodel_remove_attributevalue_color_and_more.py new file mode 100644 index 0000000..280d9c6 --- /dev/null +++ b/backend/product/migrations/0022_productimagemodel_remove_attributevalue_color_and_more.py @@ -0,0 +1,48 @@ +# Generated by Django 5.1.2 on 2025-02-11 19:19 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('product', '0021_remove_productmodel_in_pack_items_and_more'), + ] + + operations = [ + migrations.CreateModel( + name='ProductImageModel', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=30, verbose_name='نام عکس')), + ('image', models.ImageField(upload_to='product_images/')), + ], + ), + migrations.RemoveField( + model_name='attributevalue', + name='color', + ), + migrations.RemoveField( + model_name='attributevalue', + name='image', + ), + migrations.RemoveField( + model_name='attributevalue', + name='video', + ), + migrations.AddField( + model_name='productvariant', + name='color', + field=models.CharField(blank=True, max_length=7, null=True, verbose_name='رنک'), + ), + migrations.AddField( + model_name='productvariant', + name='video', + field=models.FileField(blank=True, null=True, upload_to='product_videos/', verbose_name='ویدیو'), + ), + migrations.AddField( + model_name='productvariant', + name='images', + field=models.ManyToManyField(to='product.productimagemodel', verbose_name='عکس ها'), + ), + ] diff --git a/backend/product/models.py b/backend/product/models.py index b148823..e06e872 100644 --- a/backend/product/models.py +++ b/backend/product/models.py @@ -111,7 +111,6 @@ class ProductModel(models.Model): created_at = models.DateTimeField(auto_now_add=True, verbose_name='زمان ثبت محصول') category = models.ForeignKey(SubCategoryModel, null=True, on_delete=models.SET_NULL, related_name='products', verbose_name='دسته بندی محصول') related_products = models.ManyToManyField('self', blank=True, verbose_name='محصولات مرتبط') - in_pack_items = models.ManyToManyField(InPackItems, blank=True, verbose_name='ایتم های داخل پک') @@ -198,15 +197,27 @@ class AttributeType(models.Model): class AttributeValue(models.Model): attribute_type = models.ForeignKey(AttributeType, on_delete=models.CASCADE, blank=True, null=True) value = models.CharField(verbose_name='مقدار نوع اتربیوت', max_length=100, blank=True, null=True) - color = models.CharField(verbose_name='رنک', max_length=7, blank=True, null=True) - image = models.ImageField(upload_to='product_images/') - video = models.FileField(upload_to='product_videos/', blank=True, null=True, verbose_name='ویدیو') class Meta: unique_together = ('attribute_type', 'value') def __str__(self): return f"{self.attribute_type.name}: {self.value}" + +class ProductImageModel(models.Model): + name = models.CharField(max_length=30, verbose_name='نام عکس') + image = models.ImageField(upload_to='product_images/') + + def __str__(self): + return self.name + + class Meta: + verbose_name = 'عکس محصولات' + verbose_name_plural = 'عکس های محصولات' + + + + class ProductVariant(models.Model): product = models.ForeignKey(ProductModel, on_delete=models.CASCADE, related_name='variants', verbose_name='محصول') attributes = models.ManyToManyField(AttributeValue, verbose_name='ویژگی‌ها', related_name='variant') @@ -219,9 +230,13 @@ class ProductVariant(models.Model): ('toman', 'تومان'), ('derham', 'درهم') ) + in_pack_items = models.ManyToManyField(InPackItems, blank=True, verbose_name='ایتم های داخل پک') sell = models.IntegerField(default=0, verbose_name='فروش') currency = models.CharField(verbose_name='نوع ارز', max_length=20, choices=currency_type) discount = models.SmallIntegerField(default=0, verbose_name='تخفیف') + color = models.CharField(verbose_name='رنک', max_length=7, blank=True, null=True) + images = models.ManyToManyField(ProductImageModel, verbose_name='عکس ها') + video = models.FileField(upload_to='product_videos/', blank=True, null=True, verbose_name='ویدیو') class Meta: verbose_name = 'تنوع محصول' verbose_name_plural = 'تنوع‌های محصول' diff --git a/backend/product/serializers.py b/backend/product/serializers.py index 4907698..f3bc036 100644 --- a/backend/product/serializers.py +++ b/backend/product/serializers.py @@ -30,9 +30,24 @@ class AttributeValueSerialzier(serializers.ModelSerializer): model = AttributeValue fields = "__all__" + +class InPackItemsSerialzier(serializers.ModelSerializer): + class Meta: + model = InPackItems + fields = '__all__' + +class ProductImageSerailizer(serializers.ModelSerializer): + class Meta: + model = ProductImageModel + fields = '__all__' + + + class ProductVariantSerialzier(serializers.ModelSerializer): attributes = AttributeValueSerialzier(many=True) price = serializers.SerializerMethodField() + in_pack_items = InPackItemsSerialzier(many=True) + images = ProductImageSerailizer(many=True) class Meta: model = ProductVariant exclude = ('min_price', 'max_price','sell', 'currency', 'product') @@ -42,6 +57,11 @@ class ProductVariantSerialzier(serializers.ModelSerializer): toman_price = obj.get_toman_price(dollor_price=dollor_price) return "{:,.0f} تومان".format(toman_price) + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + view_type = self.context.get('view_type', None) + if view_type == 'list': + self.fields.pop('in_pack_items', None) @@ -49,11 +69,12 @@ class ProductVariantSerialzier(serializers.ModelSerializer): class DynamicProductSerializer(serializers.ModelSerializer): - variants = ProductVariantSerialzier(many=True) + variants = serializers.SerializerMethodField() # variants_colors = serializers.SerializerMethodField() is_new = serializers.SerializerMethodField() related_products = serializers.SerializerMethodField() details = ProductDetailSerializer(many=True, read_only=True) + def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) view_type = self.context.get('view_type', 'all') @@ -74,7 +95,9 @@ class DynamicProductSerializer(serializers.ModelSerializer): 'instance': ['name', 'description', 'rating', 'slug', 'meta_description', 'meta_keywords', 'meta_rating', 'category', 'related_products', 'details', 'in_pack_items', 'variants'], 'chat': ['name', 'description', 'variants'] } - + + def get_variants(self, obj): + return ProductVariantSerialzier(instance=obj.variants.all(), many=True, context=self.context).data # def get_variants_colors(self, obj): # varients = obj.variants.all() From cf88cf57c5f0d9641b452b42dc6af96370fdd3fb Mon Sep 17 00:00:00 2001 From: Parsa Nazer Date: Tue, 11 Feb 2025 23:05:46 +0330 Subject: [PATCH 7/7] nullable value for detail model --- backend/product/models.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/product/models.py b/backend/product/models.py index e06e872..1c65209 100644 --- a/backend/product/models.py +++ b/backend/product/models.py @@ -131,9 +131,9 @@ class ProductModel(models.Model): class DetailModel(models.Model): title = models.CharField(max_length=50, verbose_name='عنوان') detail_text1 = models.CharField(max_length=150 , verbose_name='متن جزیات ۱') - detail_text2 = models.CharField(max_length=150 , verbose_name='متن جزیات ۲') - detail_text3 = models.CharField(max_length=150 , verbose_name='متن جزیات ۳') - detail_text4 = models.CharField(max_length=150 , verbose_name='متن جزیات ۴') + detail_text2 = models.CharField(max_length=150 , verbose_name='متن جزیات ۲', blank=True, null=True) + detail_text3 = models.CharField(max_length=150 , verbose_name='متن جزیات ۳', blank=True, null=True) + detail_text4 = models.CharField(max_length=150 , verbose_name='متن جزیات ۴', blank=True, null=True) def __str__(self): return self.title @@ -210,7 +210,7 @@ class ProductImageModel(models.Model): def __str__(self): return self.name - + class Meta: verbose_name = 'عکس محصولات' verbose_name_plural = 'عکس های محصولات'