Files
hossein-por-shop/backend/product/models.py
T
2025-04-21 23:28:17 +03:30

276 lines
12 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from django.db import models
from django.utils.text import slugify
from account.models import User
from django.urls import reverse
import requests
from django.utils.translation import gettext_lazy as _
from django.core.exceptions import ValidationError
class MainCategoryModel(models.Model):
name = models.CharField(max_length=50, verbose_name='نام دسته بندی')
slug = models.SlugField(max_length=50, unique=True, help_text="اسم دسته را برای مسیر به انگلیسی و بدون فاصله وارد کنید")
icon = models.ImageField(upload_to='category_model/',verbose_name='آیکون', blank=True, null=True)
meta_title = models.CharField(max_length=60, verbose_name="عنوان متا", help_text="عنوان متا برای SEO", blank=True, null=True)
meta_description = models.TextField(max_length=160, verbose_name="توضیحات متا", help_text="توضیحات متا برای SEO", blank=True, null=True)
class Meta:
verbose_name = "دسته‌بندی اصلی"
verbose_name_plural = "دسته‌بندی‌هااصلی"
def __str__(self):
return self.name
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.name, allow_unicode=True)
super().save(*args, **kwargs)
class SubCategoryModel(models.Model):
name = models.CharField(max_length=50, verbose_name='نام دسته بندی')
slug = models.SlugField(max_length=50, unique=True, help_text="اسم دسته را برای مسیر به انگلیسی و بدون فاصله وارد کنید")
image = models.ImageField(upload_to='category_model/',verbose_name='عکس', blank=True, null=True)
icon = models.ImageField(upload_to='category_model/',verbose_name='آیکون', blank=True, null=True)
meta_title = models.CharField(max_length=60, verbose_name="عنوان متا", help_text="عنوان متا برای SEO", blank=True, null=True)
meta_description = models.TextField(max_length=160, verbose_name="توضیحات متا", help_text="توضیحات متا برای SEO", blank=True, null=True)
parent = models.ForeignKey(MainCategoryModel, on_delete=models.CASCADE, related_name='subcategorys', verbose_name='دسته‌بندی والد')
show = models.BooleanField(default=False, verbose_name='نمایش در خانه')
class Meta:
verbose_name = "زیر دسته‌بندی"
verbose_name_plural = "زیر دسته‌بندی‌ها"
def __str__(self):
return self.name
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.name, allow_unicode=True)
super().save(*args, **kwargs)
class DollorModel(models.Model):
price = models.FloatField(null=True, blank=True, verbose_name='قیمت دلار')
defualt_price = models.FloatField(null=True, blank=True, default=80000.0, verbose_name='قیمت دستی')
# these fields will avoid dublicate of this model
unique = (('unique', 'unique'),)
unique_filed = models.CharField(max_length=20, choices=unique, unique=True, default='unique')
def __str__(self):
return str(self.price)
def save(self, *args, **kwargs):
if not self.price:
self.update_price()
super().save(*args, **kwargs)
def update_price(self):
self.price = self.get_usd_price()
def get_usd_price(self):
try:
api_usd = "https://api.nobitex.ir/v2/orderbook/USDTIRT"
response = requests.get(api_usd)
data = response.json()
price = int(data["lastTradePrice"])
price_in_usd = price / 10.0
print('\n\nprice from api \n\n')
except:
if self.price:
print('\n\nprice from last price \n\n')
return self.price
else:
print('\n\nprice from defualt price \n\n')
return self.defualt_price
return price_in_usd
class Meta:
verbose_name = 'مدل دلار'
verbose_name_plural = 'مدل دلار'
class InPackItems(models.Model):
item_title = models.CharField(max_length=50)
cover = models.ImageField(upload_to='product_items/', verbose_name='کاور ایتم')
class Meta:
verbose_name = 'ایتم داخل پک'
verbose_name_plural = 'ایتم های داخل پک'
def __str__(self):
return self.item_title
class ProductModel(models.Model):
name = models.CharField(max_length=255, verbose_name='نام')
description = models.TextField(verbose_name='توضیحات')
rating = models.PositiveIntegerField(default=0, verbose_name='امتیاز')
show = models.BooleanField(default=False, verbose_name='نمایش در خانه')
view = models.IntegerField(default=0, verbose_name='بازدید')
slug = models.SlugField(max_length=50, unique=True, blank=True, null=True, allow_unicode=True,
verbose_name='نام یکتا', help_text="این فیلد را خالی بگذارید")
meta_description = models.CharField(max_length=300, blank=True, null=True, help_text='این فیلد را حتما پر کنید', verbose_name='متا دیسکریپشن')
meta_keywords = models.CharField(max_length=300, blank=True, null=True, help_text='این فیلد را حتما پر کنید', verbose_name='متا کیورد')
meta_rating = models.FloatField(default=5, help_text='امتیاز محصول', verbose_name='متا ریتینگ')
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='محصولات مرتبط')
def __str__(self):
return self.name
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.name, allow_unicode=True)
super().save(*args, **kwargs)
class Meta:
verbose_name = 'محصول'
verbose_name_plural = 'محصولات'
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='متن جزیات ۲', 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
class Meta:
verbose_name = 'مدل جزیات'
verbose_name_plural = 'مدل های جزیات'
class ProductDetailCategory(models.Model):
title = models.CharField(max_length=40, verbose_name='عنوان')
def __str__(self):
return self.title
class Meta:
verbose_name = 'دسته بندی جزيات'
verbose_name_plural = 'دسته بندی های جزيیات'
class CommentModel(models.Model):
product = models.ForeignKey(ProductModel, on_delete=models.CASCADE, related_name='comments', verbose_name='محصول')
title = models.CharField(max_length=50)
content = models.TextField(verbose_name='محتوای نظر')
user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='کاربر')
timestamp = models.DateTimeField(auto_now_add=True, verbose_name='زمان ثبت کامنت')
status_types = (
('reviewed_and_confirmed', 'بررسی و تایید شده'),
('reviewed_and_rejected', 'بررسی شده و رد شده'),
('not_reviwed', 'بررسی نشده'),
)
review_status = models.CharField(default='not_reviwed', verbose_name='نشان دادن کامنت', max_length=30, choices=status_types)
class Meta:
verbose_name = 'نظر'
verbose_name_plural = 'نظرات'
def __str__(self):
return f"{self.user}-{self.content[:30]}"
class AttributeType(models.Model):
name = models.CharField(verbose_name='نام نوع متغییر', max_length=100)
def __str__(self):
return self.name
class Meta:
verbose_name = 'نوع متغییر محصول'
verbose_name_plural = 'نوع های متغییر محصول'
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)
class Meta:
unique_together = ('attribute_type', 'value')
verbose_name = 'مقدار متغییر محصول'
verbose_name_plural = 'مقدار های متغییر محصول'
def __str__(self):
return f"{self.attribute_type}: {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 ProductDetailModel(models.Model):
detail_category = models.ForeignKey(ProductDetailCategory, on_delete=models.CASCADE, verbose_name='دسته بندی جزيات', blank=True, null=True)
detail = models.ManyToManyField(DetailModel, verbose_name='جزيات ها')
class Meta:
verbose_name = 'جزیات محصول'
verbose_name_plural = 'جزیات محصول ها'
def __str__(self):
return f'جزيیات محصول {self.detail_category.title} - {self.detail.title}'
class ProductVariant(models.Model):
product = models.ForeignKey(ProductModel, on_delete=models.CASCADE, related_name='variants', verbose_name='محصول')
product_attributes = models.ManyToManyField(AttributeValue, verbose_name='ویژگی‌ها', related_name='variant')
in_stock = models.PositiveIntegerField(default=0, verbose_name='تعداد موجود')
price = models.PositiveIntegerField(verbose_name='قیمت محاسبه شده', blank=True, null=True)
input_price = models.PositiveIntegerField(default=0, verbose_name='قیمت ورودی')
min_price = models.PositiveIntegerField(verbose_name='قیمت کف', help_text='این قیمت برای کف قیمتی محصول در نظر گرفته میشود')
currency_type = (
('dollor', 'دلار'),
('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='ویدیو')
details = models.ManyToManyField(ProductDetailModel, verbose_name='جزییات محصول', related_name='product')
class Meta:
verbose_name = 'تنوع محصول'
verbose_name_plural = 'تنوع‌های محصول'
def __str__(self):
return f"{self.product.name} - {', '.join(str(attr) for attr in self.product_attributes.all())}"
def set_or_update_price(self, dollor_price=None):
if not dollor_price:
dollor_object, _ = DollorModel.objects.get_or_create(unique_filed='unique')
dollor_price = dollor_object.price
if dollor_price is None:
raise ValidationError({"dollor_price": "The 'dollor_price' must be provided in the context for dollar pricing."})
dollar_to_dirham = 0.27
if self.currency == 'toman':
toman_price = self.input_price
elif self.currency == 'dollor':
toman_price = self.input_price * dollor_price
elif self.currency == 'derham':
toman_price = self.input_price * dollor_price * dollar_to_dirham
else:
toman_price = self.input_price
self.price = max(toman_price, self.min_price)
def save(self, *args, **kwargs):
self.set_or_update_price()
super().save(*args, **kwargs)