Files
vontor-cz/backend/vontor_cz/custom_fields.py

52 lines
1.5 KiB
Python

import os
from io import BytesIO
from PIL import Image
from django.db import models
from django.core.files.base import ContentFile
import logging
logger = logging.getLogger(__name__)
class WebPImageField(models.ImageField):
"""
A custom ImageField that converts uploaded images to WebP automatically.
Inherits from models.ImageField (description: "Image").
Accepts the same arguments:
verbose_name, name, upload_to, storage,
width_field, height_field, **kwargs
"""
def pre_save(self, model_instance, add):
file_obj = getattr(model_instance, self.attname)
if file_obj and not file_obj._committed:
self._convert_to_webp(file_obj)
return super().pre_save(model_instance, add)
def _convert_to_webp(self, file_obj):
try:
file_obj.open()
image = Image.open(file_obj)
if image.format == 'WEBP':
image.close()
return
if image.mode == 'P':
image = image.convert('RGBA')
elif image.mode not in ('RGBA', 'LA'):
image = image.convert('RGB')
image_io = BytesIO()
image.save(image_io, format='WEBP', quality=85, optimize=True)
image.close()
new_filename = os.path.splitext(file_obj.name)[0] + '.webp'
file_obj.save(new_filename, ContentFile(image_io.getvalue()), save=False)
except Exception as e:
logger.error(f"WebP conversion failed: {e}")