Added asynch thumbnail generation
rodzic
b45b2f60cf
commit
45993e32dd
|
@ -1,3 +1,3 @@
|
||||||
from .celery import app as celery_app
|
from .celery import app as celery_app
|
||||||
|
|
||||||
__all__ = ('celery_app',)
|
__all__ = ('celery_app',)
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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,
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
|
@ -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=""),
|
||||||
|
),
|
||||||
|
]
|
|
@ -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}"
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue