ref: use thumbnail image instead of size limit

This commit is contained in:
relikd
2024-07-28 22:41:04 +02:00
parent d009d3ab3a
commit b98b882665
4 changed files with 24 additions and 36 deletions

View File

@@ -69,7 +69,7 @@ class Migration(migrations.Migration):
('sort', models.IntegerField(default=0, verbose_name='Sortierung')),
('isExtended', models.BooleanField(verbose_name='Bis 1.1.2025 verstecken')),
('title', models.CharField(max_length=100, verbose_name='Titel')),
('image', common.form.img_with_preview.FileWithImagePreview(blank=True, null=True, upload_to=app.models.place.overwrite_img_upload, verbose_name='Bild')),
('image', common.form.img_with_preview.ThumbnailImageField(blank=True, null=True, upload_to=app.models.place.overwrite_img_upload, verbose_name='Bild')),
('audio', common.form.audio_file.AudioFileField(blank=True, null=True, upload_to=app.models.place.overwrite_audio_upload, verbose_name='Audio')),
('location', map_location.fields.LocationField(blank=True, null=True, verbose_name='Position')),
('description', tinymce.models.HTMLField(verbose_name='Beschreibung')),

View File

@@ -13,7 +13,7 @@ from map_location.fields import LocationField
from app.models.category import Category
from common.form.audio_file import AudioFileField
from common.form.img_with_preview import FileWithImagePreview
from common.form.img_with_preview import ThumbnailImageField
def overwrite_img_upload(instance: 'Place', filename: str):
@@ -38,8 +38,8 @@ class Place(models.Model):
sort = models.IntegerField('Sortierung', default=0)
isExtended = models.BooleanField('Bis 1.1.2025 verstecken')
title = models.CharField('Titel', max_length=100)
image = FileWithImagePreview('Bild', blank=True, null=True,
upload_to=overwrite_img_upload)
image = ThumbnailImageField('Bild', blank=True, null=True,
upload_to=overwrite_img_upload) # type: ignore
audio = AudioFileField('Audio', blank=True, null=True,
upload_to=overwrite_audio_upload)
location = LocationField('Position', blank=True, null=True, options={

View File

@@ -1,13 +1,20 @@
from django import forms
from django.conf import settings
from django.contrib.admin.widgets import AdminFileWidget
from django.core.validators import FileExtensionValidator
from django.core.files.uploadedfile import UploadedFile
from django.db import models
from django.forms import FileInput, widgets
from django.forms import widgets
from common.validators import MaxFilesizeValidator, readableToInt
from PIL import Image, ImageOps
MAX_UPLOAD_SIZE = '312 KB'
def makeThumnail(data: UploadedFile, size: 'tuple[int, int]'):
with Image.open(data) as img:
ImageOps.exif_transpose(img, in_place=True)
img.thumbnail(size)
if img.mode != 'RGB':
img = img.convert('RGB')
data.seek(0)
data.truncate()
img.save(data, 'jpeg')
class ImageFileWidget(widgets.ClearableFileInput):
@@ -19,38 +26,19 @@ class ImageFileWidget(widgets.ClearableFileInput):
return context
class ImgField(forms.FileField):
widget = ImageFileWidget
default_validators = [
FileExtensionValidator(['jpg', 'jpeg', 'png']),
MaxFilesizeValidator(MAX_UPLOAD_SIZE),
]
def widget_attrs(self, widget):
attrs = super().widget_attrs(widget)
if isinstance(widget, FileInput) and 'accept' not in widget.attrs:
attrs.setdefault('accept', 'image/png,image/jpeg') # image/*
if isinstance(widget, ImageFileWidget):
attrs.update({
'data-upload-limit': readableToInt(MAX_UPLOAD_SIZE),
'data-upload-limit-str': MAX_UPLOAD_SIZE,
'onchange': 'validate_upload_limit(this)',
})
return attrs
class FileWithImagePreview(models.FileField): # use ImageField to omit Pillow
class ThumbnailImageField(models.ImageField):
__del_image_on_save = False
def formfield(self, **kwargs):
if kwargs['widget'] is AdminFileWidget:
# Override admin widget. Defined by ImgField anyway
del kwargs['widget']
return super().formfield(**{'form_class': ImgField, **kwargs})
kwargs['widget'] = ImageFileWidget
return super().formfield(**kwargs)
def save_form_data(self, instance, data):
if data is False:
self.__del_image_on_save = True
if isinstance(data, UploadedFile):
makeThumnail(data, (1200, 900)) # only on create
# on update: django.db.models.fields.files.ImageFieldFile
super().save_form_data(instance, data)
def pre_save(self, model_instance, add):

View File

@@ -1,4 +1,4 @@
Django==4.2.13
Django>=4.2,<5
Pillow==10.4.0
django_colorfield==0.11.0
django-tinymce==4.1.0