feat: created product image model
This commit is contained in:
+104
-3
@@ -1,13 +1,17 @@
|
||||
from decimal import Decimal
|
||||
from io import BytesIO
|
||||
from uuid import uuid4
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.core.files.base import ContentFile
|
||||
from django.db import models
|
||||
from django.utils import timezone
|
||||
from django.utils.text import gettext_lazy as _
|
||||
from django.utils.text import slugify
|
||||
|
||||
from PIL import Image
|
||||
|
||||
from config.models import SingletonModel
|
||||
from shop.settings import CURRENCY_CODES
|
||||
|
||||
@@ -103,9 +107,6 @@ class Product(TimestampedModel):
|
||||
default=False, verbose_name=_("es un activo digital")
|
||||
)
|
||||
url = models.URLField(blank=True, verbose_name=_("URL de descarga"))
|
||||
images = models.ManyToManyField(
|
||||
"files.FileUpload", blank=True, verbose_name=_("imágenes")
|
||||
)
|
||||
tags = models.ManyToManyField("shop.Tag", blank=True, verbose_name=_("etiquetas"))
|
||||
categories = models.ManyToManyField(
|
||||
"shop.ProductCategory", blank=True, verbose_name=_("categorías")
|
||||
@@ -182,6 +183,106 @@ class ProductPrice(TimestampedModel):
|
||||
ordering = ("-date",)
|
||||
|
||||
|
||||
class ProductImage(models.Model):
|
||||
product = models.ForeignKey(
|
||||
"shop.Product",
|
||||
on_delete=models.CASCADE,
|
||||
blank=False,
|
||||
null=False,
|
||||
verbose_name=_("Producto"),
|
||||
related_name="images",
|
||||
)
|
||||
original = models.ImageField(
|
||||
upload_to="uploads", blank=False, null=False, verbose_name=_("Imagen original")
|
||||
)
|
||||
|
||||
xl = models.ImageField(
|
||||
upload_to="uploads", blank=True, null=True, verbose_name=_("XL")
|
||||
)
|
||||
xl_dark = models.ImageField(
|
||||
upload_to="uploads", blank=True, null=True, verbose_name=_("XL (fondo oscuro)")
|
||||
)
|
||||
|
||||
l = models.ImageField(
|
||||
upload_to="uploads", blank=True, null=True, verbose_name=_("L")
|
||||
)
|
||||
l_dark = models.ImageField(
|
||||
upload_to="uploads", blank=True, null=True, verbose_name=_("L (fondo oscuro)")
|
||||
)
|
||||
|
||||
m = models.ImageField(
|
||||
upload_to="uploads", blank=True, null=True, verbose_name=_("M")
|
||||
)
|
||||
m_dark = models.ImageField(
|
||||
upload_to="uploads", blank=True, null=True, verbose_name=_("M (fondo oscuro)")
|
||||
)
|
||||
|
||||
s = models.ImageField(
|
||||
upload_to="uploads", blank=True, null=True, verbose_name=_("S")
|
||||
)
|
||||
s_dark = models.ImageField(
|
||||
upload_to="uploads", blank=True, null=True, verbose_name=_("S (fondo oscuro)")
|
||||
)
|
||||
|
||||
xs = models.ImageField(
|
||||
upload_to="uploads", blank=True, null=True, verbose_name=_("XS")
|
||||
)
|
||||
xs_dark = models.ImageField(
|
||||
upload_to="uploads", blank=True, null=True, verbose_name=_("XS (fondo oscuro)")
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return self.original.url
|
||||
|
||||
def make_square(self, image, max_size=512, fill_color="#000000"):
|
||||
width, height = image.size
|
||||
|
||||
if width > height:
|
||||
ratio = width / max_size
|
||||
else:
|
||||
ratio = height / max_size
|
||||
|
||||
new_width = int(width / ratio)
|
||||
new_height = int(height / ratio)
|
||||
|
||||
resized_image = image.resize((new_width, new_height), Image.Resampling.LANCZOS)
|
||||
|
||||
new_image = Image.new("RGB", (max_size, max_size), fill_color)
|
||||
|
||||
position_x = int((max_size - new_width) / 2)
|
||||
position_y = int((max_size - new_height) / 2)
|
||||
|
||||
new_image.paste(resized_image, (position_x, position_y))
|
||||
|
||||
return new_image
|
||||
|
||||
def get_resized_image(self, image, size, fill_color="#000000"):
|
||||
image = Image.open(image)
|
||||
image = self.make_square(image, size, fill_color)
|
||||
buffer = BytesIO()
|
||||
image.save(fp=buffer, format="WEBP")
|
||||
|
||||
return ContentFile(buffer.getvalue(), name=f"{self.product.slug}_{size}.webp")
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
self.xl = self.get_resized_image(self.original, 1024, fill_color="#FFFFFF")
|
||||
self.xl_dark = self.get_resized_image(self.original, 1024)
|
||||
|
||||
self.l = self.get_resized_image(self.original, 512, fill_color="#FFFFFF")
|
||||
self.l_dark = self.get_resized_image(self.original, 512)
|
||||
|
||||
self.m = self.get_resized_image(self.original, 256, fill_color="#FFFFFF")
|
||||
self.m_dark = self.get_resized_image(self.original, 256)
|
||||
|
||||
self.s = self.get_resized_image(self.original, 128, fill_color="#FFFFFF")
|
||||
self.s_dark = self.get_resized_image(self.original, 128)
|
||||
|
||||
self.xs = self.get_resized_image(self.original, 96, fill_color="#FFFFFF")
|
||||
self.xs_dark = self.get_resized_image(self.original, 96)
|
||||
|
||||
return super().save(*args, **kwargs)
|
||||
|
||||
|
||||
class ProductBatch(TimestampedModel):
|
||||
code = models.CharField(
|
||||
max_length=32, unique=True, db_index=True, verbose_name=_("código")
|
||||
|
||||
Reference in New Issue
Block a user