Added asynch thumbnail generation

feature/thumbnails
KarolG 2023-08-04 18:24:12 +02:00
rodzic b45b2f60cf
commit 45993e32dd
7 zmienionych plików z 66 dodań i 14 usunięć

Wyświetl plik

@ -1,3 +1,3 @@
from .celery import app as celery_app from .celery import app as celery_app
__all__ = ('celery_app',) __all__ = ('celery_app',)

Wyświetl plik

@ -52,7 +52,8 @@ INSTALLED_APPS = [
"rest_framework", "rest_framework",
"phonenumber_field", "phonenumber_field",
"django_celery_results", "django_celery_results",
"django_celery_beat" "django_celery_beat",
"easy_thumbnails",
] ]
MIDDLEWARE = [ MIDDLEWARE = [
@ -197,3 +198,7 @@ CELERY_TASK_TIME_LIMIT = 30 * 60
# CELERY_RESULT_BACKEND_DB = f'db+mysql+pymysql://{os.environ.get("MYSQL_USER")}:{os.environ.get("MYSQL_PASSWORD")}@db/{os.environ.get("MYSQL_DATABASE")}' # CELERY_RESULT_BACKEND_DB = f'db+mysql+pymysql://{os.environ.get("MYSQL_USER")}:{os.environ.get("MYSQL_PASSWORD")}@db/{os.environ.get("MYSQL_DATABASE")}'
CELERY_BROKER_URL = f'amqp://{os.environ.get("RABBITMQ_DEFAULT_USER")}:{os.environ.get("RABBITMQ_DEFAULT_PASS")}@rabbit//' CELERY_BROKER_URL = f'amqp://{os.environ.get("RABBITMQ_DEFAULT_USER")}:{os.environ.get("RABBITMQ_DEFAULT_PASS")}@rabbit//'
CELERY_TASK_RESULT_EXPIRES = 18000 CELERY_TASK_RESULT_EXPIRES = 18000
# EASY_THUMBNAILS settings
THUMBNAIL_DEFAULT_STORAGE = 'django.core.files.storage.FileSystemStorage'

Wyświetl plik

@ -0,0 +1,16 @@
from celery import shared_task
from easy_thumbnails.files import get_thumbnailer
@shared_task
def generate_thumbnails(image_instance):
thumbnailer = get_thumbnailer(image_instance)
small_thumbnail = thumbnailer.get_thumbnail({'size': (40, 60), 'crop': False})
medium_thumbnail = thumbnailer.get_thumbnail({'size': (80, 120), 'crop': False})
large_thumbnail = thumbnailer.get_thumbnail({'size': (160, 240), 'crop': False})
return {
'small': small_thumbnail.url,
'medium': medium_thumbnail.url,
'large': large_thumbnail.url,
}

Wyświetl plik

@ -11,3 +11,4 @@ pdfkit==1.0.0
celery==5.3.1 celery==5.3.1
django-celery-beat==2.5.0 django-celery-beat==2.5.0
django-celery-results==2.5.1 django-celery-results==2.5.1
easy_thumbnails==2.8.5

Wyświetl plik

@ -0,0 +1,18 @@
# Generated by Django 4.1.10 on 2023-08-04 03:05
from django.db import migrations
import easy_thumbnails.fields
class Migration(migrations.Migration):
dependencies = [
("store", "0006_documenttemplate_created_at_orderdocument_sent"),
]
operations = [
migrations.AlterField(
model_name="productimage",
name="image",
field=easy_thumbnails.fields.ThumbnailerImageField(upload_to=""),
),
]

Wyświetl plik

@ -26,6 +26,9 @@ from store.utils import (
send_mail send_mail
) )
from easy_thumbnails.fields import ThumbnailerImageField
from artel.tasks import generate_thumbnails
class ProductAuthor(models.Model): class ProductAuthor(models.Model):
name = models.CharField(max_length=255) name = models.CharField(max_length=255)
@ -89,7 +92,7 @@ class ProductImage(models.Model):
template = ParentalKey( template = ParentalKey(
ProductTemplate, on_delete=models.CASCADE, related_name="images" ProductTemplate, on_delete=models.CASCADE, related_name="images"
) )
image = models.ImageField() image = ThumbnailerImageField()
class Product(ClusterableModel): class Product(ClusterableModel):
@ -113,7 +116,10 @@ class Product(ClusterableModel):
images = self.template.images.all() images = self.template.images.all()
print(images) print(images)
if images: if images:
return images.first().image image_instance = images.first().image
thumbnails = generate_thumbnails(image_instance)
return thumbnails
return None
@property @property
def tags(self): def tags(self):
@ -166,6 +172,7 @@ class ProductListPage(Page):
FieldPanel("tags") FieldPanel("tags")
] ]
class CustomerData(models.Model): class CustomerData(models.Model):
name = models.CharField(max_length=255) name = models.CharField(max_length=255)
surname = models.CharField(max_length=255) surname = models.CharField(max_length=255)
@ -179,7 +186,7 @@ class CustomerData(models.Model):
@property @property
def full_name(self): def full_name(self):
return f"{self.name} {self.surname}" return f"{self.name} {self.surname}"
@property @property
def full_address(self): def full_address(self):
return f"{self.street}, {self.zip_code} {self.city}, {self.country}" return f"{self.street}, {self.zip_code} {self.city}, {self.country}"

Wyświetl plik

@ -1,15 +1,20 @@
{% load static %} {% load static %}
{% load thumbnail %}
<div class="card h-100" > <div class="card h-100" >
<div class="card-header text-truncate">{{item.title}}</div> <div class="card-header text-truncate">{{item.title}}</div>
<div class="card-body p-0"> <div class="card-body p-0 h-70">
<img src="{{item.main_image.url}}" class="img-fluid rounded mx-auto d-block" style="width: 10rem; height: 15rem;" alt="{{item.title}}">
<div class="card-footer row d-flex mt-3 m-0"> <img src="{{ item.main_image.small }}" class="d-block d-sm-block d-md-none img-fluid rounded mx-auto" alt="{{item.title}}">
<div class="col">
<input type="number" id="quantity{{item.id}}" name="quantity" min="1" value="1" class="form-control form-control-sm"> <img src="{{ item.main_image.medium }}" class="d-none d-sm-none d-md-block d-lg-none img-fluid rounded mx-auto" alt="{{item.title}}">
</div>
<div class="col text-end"> <img src="{{ item.main_image.large }}" class="d-none d-lg-block d-xl-block img-fluid rounded mx-auto" alt="{{item.title}}">
</div>
<div class="card-footer row d-flex mt-3 m-0">
<div class="col">
<input type="number" id="quantity{{item.id}}" name="quantity" min="1" value="1" class="form-control form-control-sm">
</div>
<div class="col text-end">
<button class="btn btn-outline-success add-to-cart-button" <button class="btn btn-outline-success add-to-cart-button"
data-product-id="{{item.id}}" data-product-id="{{item.id}}"
data-csrf-token="{{csrf_token}}" data-csrf-token="{{csrf_token}}"
@ -18,7 +23,7 @@
> >
<img src="{% static 'images/icons/cart.svg' %}" style="width: 1rem; height: 1rem;" alt="Koszyk"/> <img src="{% static 'images/icons/cart.svg' %}" style="width: 1rem; height: 1rem;" alt="Koszyk"/>
</button> </button>
</div>
</div> </div>
</div> </div>
</div> </div>