Browse Source

Use django-imagefield instead of imagekit; admin improvements.

master
Erik Stein 3 years ago
parent
commit
e631033258
  1. 71
      shared/media_archive/admin.py
  2. 1
      shared/media_archive/conf.py
  3. 73
      shared/media_archive/models.py
  4. 4
      shared/media_archive/templates/imagekit/admin/selectable_thumbnail.html

71
shared/media_archive/admin.py

@ -2,12 +2,11 @@ from django import VERSION as DJANGO_VERSION
from django.contrib import admin
from django.contrib.admin.filters import ChoicesFieldListFilter, FieldListFilter
from django.db.models import Count
from django.template.loader import render_to_string
from django.utils.encoding import smart_text
from django.utils.html import format_html, mark_safe
from django.utils.html import format_html, mark_safe, strip_tags
from django.utils.translation import gettext_lazy as _
from imagekit.admin import AdminThumbnail
from .conf import USE_TRANSLATABLE_FIELDS
from .forms import MediaCategoryAdminForm
from . import admin_actions, mixins, models
@ -22,6 +21,38 @@ else:
return fieldname
class AdminThumbnail:
# Taken from ImageKit and adapted for django-imagefield
image_field = 'file'
format_name = 'admin_thumbnail'
template = 'imagekit/admin/selectable_thumbnail.html'
short_description = _('Thumbnail')
allow_tags = True
def __init__(self, image_field=None, format_name=None, template=None):
if image_field:
self.image_field = image_field
if format_name:
self.format_name = format_name
if template:
self.template = template
def __call__(self, obj):
if callable(self.image_field):
thumbnail = self.image_field(obj)
else:
thumbnail = getattr(getattr(obj, self.image_field), self.format_name)
original_image = getattr(thumbnail, 'source', None) or thumbnail
template = self.template or 'imagekit/admin/thumbnail.html'
return render_to_string(template, {
'model': obj,
'thumbnail': thumbnail,
'original_image': original_image,
})
class CategoryFieldListFilter(ChoicesFieldListFilter):
"""
Customization of ChoicesFilterSpec which sorts in the user-expected format.
@ -121,36 +152,42 @@ class MediaAdminBase(admin_actions.MediaBaseActionsMixin, mixins.DropUploadAdmin
fieldsets = (
(None, {
'fields': [
'is_public',
('file', 'image_ppoi'),
*i18n_fields('caption'),
*i18n_fields('name'),
'role',
('file', 'image_ppoi'),
(
'is_public',
'role',
),
]}),
(_("Texte"), {
(_("Bildnachweise"), {
'fields': [
*i18n_fields('caption'),
*i18n_fields('credits'),
*i18n_fields('copyright'),
]}),
(_("Ordnung"), {
(_("Verwaltung"), {
'classes': ['collapse'],
'fields': [
'categories',
]}),
)
filter_horizontal = ['categories']
admin_thumbnail = AdminThumbnail(
image_field='thumbnail',
template='imagekit/admin/selectable_thumbnail.html')
admin_thumbnail.short_description = _("Foto")
admin_thumbnail = AdminThumbnail()
# TODO class Media: add switch_languages script
def get_name_display(self, obj):
caption = strip_tags(obj.caption)
if obj.name and obj.name != caption:
caption = mark_safe(f"<br>{caption}")
else:
caption = ""
return format_html(
"<small>{categories}</small><br>{caption}",
"<small>{categories}</small><br>{name}{caption}",
categories=", ".join([str(p) for p in obj.categories.all()]),
caption=str(obj),
name=str(obj),
caption=caption,
)
get_name_display.short_description = _("Name")
get_name_display.admin_order_field = lang_suffix(fieldname='name')
@ -189,9 +226,7 @@ class ImageGalleryRelInline(admin.TabularInline):
verbose_name = _("Bild")
verbose_name_plural = _("Bilder")
admin_thumbnail = AdminThumbnail(
image_field=image_thumbnail_image,
template='imagekit/admin/selectable_thumbnail.html')
admin_thumbnail = AdminThumbnail()
admin_thumbnail.short_description = _("Foto")

1
shared/media_archive/conf.py

@ -1,5 +1,6 @@
from django.conf import settings
USE_TRANSLATABLE_FIELDS = (
getattr(settings, 'CONTENT_PLUGINS_USE_TRANSLATABLE_FIELDS', False) or
getattr(settings, 'USE_TRANSLATABLE_FIELDS', False)

73
shared/media_archive/models.py

@ -1,14 +1,15 @@
import logging
import posixpath
import re
from functools import partial
from django.db import models
from django.utils.html import strip_tags
from django.utils.text import Truncator
from django.utils.translation import ugettext_lazy as _
from imagefield.fields import ImageField, PPOIField
from imagekit.models import ImageSpecField
from imagekit.processors import Adjust, Thumbnail, ResizeToFit, ResizeToFill
from shared.utils.text import html_to_text, sanitized_html
from shared.utils.models.slugs import DowngradingSlugField, slugify
from .conf import UPLOAD_TO, USE_TRANSLATABLE_FIELDS
@ -34,7 +35,7 @@ class MediaCategoryManager(models.Manager):
class MediaCategory(models.Model):
name = models.CharField(_("name"), max_length=200)
name = models.CharField(_("name"), blank=True, max_length=200)
parent = models.ForeignKey(
'self', blank=True, null=True,
on_delete=models.CASCADE,
@ -78,7 +79,8 @@ class Gallery(models.Model):
help_text=_("Publicly visible name."))
slug = models.SlugField(_("Slug"), null=True, blank=True)
credits = TranslatableCharField(_("Credits"), null=True, blank=True, max_length=500)
caption = TranslatableCleansedRichTextField(_("Caption"), null=True, blank=True)
caption = TranslatableCleansedRichTextField(_("Caption"),
null=True, blank=True, config_name='caption')
is_public = models.BooleanField(_("Active"), default=False)
order_index = models.PositiveIntegerField(_("Order Index"), default=0)
# background_color = models.ForeignKey('site_pages.Color', on_delete=models.PROTECT,
@ -165,8 +167,8 @@ class MediaRole(models.Model):
name = TranslatableCharField(_("name"), max_length=200)
class Meta:
verbose_name = _("Bild-Typ")
verbose_name_plural = _("Bild-Typen")
verbose_name = _("Art")
verbose_name_plural = _("Arten")
ordering = i18n_fields('name')
def __str__(self):
@ -194,7 +196,9 @@ class MediaBase(DeleteOldFileMixin, models.Model):
verbose_name=_("Typ"),
null=True, blank=True)
name = TranslatableCharField(_("Name"), max_length=200, null=True, blank=True)
caption = TranslatableCleansedRichTextField(_("Bildunterschrift"), blank=True)
caption = TranslatableCleansedRichTextField(_("Bildunterschrift"), blank=True,
config_name='caption',
cleanse=partial(sanitized_html, config_name='caption'))
credits = TranslatableCharField(_("Credits"), max_length=500, null=True, blank=True)
copyright = TranslatableCharField(_('Rechteinhaber/in'), max_length=2000, blank=True)
@ -211,6 +215,11 @@ class MediaBase(DeleteOldFileMixin, models.Model):
return self.name or strip_tags(self.caption) or posixpath.basename(self.file.name)
def save(self, *args, **kwargs):
if not self.name:
if self.caption:
self.name = Truncator(html_to_text(self.caption)).chars(200, truncate='')
else:
self.name = Truncator(posixpath.basename(self.file.name)).chars(200, truncate='')
if self.file:
try:
self.file_size = self.file.size
@ -221,14 +230,6 @@ class MediaBase(DeleteOldFileMixin, models.Model):
class Image(MediaBase):
image_width = models.PositiveIntegerField(
_("image width"), blank=True, null=True, editable=False
)
image_height = models.PositiveIntegerField(
_("image height"), blank=True, null=True, editable=False
)
image_ppoi = PPOIField(_("primary point of interest"))
# file = models.ImageField(_("Datei"))
file = ImageField(
_("image"),
max_length=200,
@ -238,43 +239,11 @@ class Image(MediaBase):
ppoi_field="image_ppoi",
blank=True,
)
logo_image = ImageSpecField(source='file',
processors=[ResizeToFit(150, 150)])
thumbnail = ImageSpecField(source='file',
processors=[Adjust(contrast=1.2, sharpness=1.1),
Thumbnail(100, 50)],
format='JPEG', options={'quality': 90})
square_image = ImageSpecField(source='file',
processors=[ResizeToFill(800, 800)],
format='JPEG', options={'quality': 90})
small_article_image = ImageSpecField(source='file',
processors=[ResizeToFit(400, 400)],
format='JPEG', options={'quality': 90})
article_image = ImageSpecField(source='file',
processors=[ResizeToFit(800, 800)],
format='JPEG', options={'quality': 90})
gallery_image = ImageSpecField(source='file',
processors=[ResizeToFit(1200, 1200)],
format='JPEG', options={'quality': 90})
gallery_image_thumbnail = ImageSpecField(source='file',
processors=[
Adjust(contrast=1.2, sharpness=1.1),
# ResizeToFit(180, 120)
ResizeToFit(220, 155)
],
format='JPEG', options={'quality': 90})
lightbox_image = ImageSpecField(source='file',
processors=[ResizeToFit(1600, 1600)],
format='JPEG', options={'quality': 90})
highres_image = lightbox_image
image_width = models.PositiveIntegerField(
_("image width"), blank=True, null=True, editable=False)
image_height = models.PositiveIntegerField(
_("image height"), blank=True, null=True, editable=False)
image_ppoi = PPOIField(_("primary point of interest"))
type = 'image'

4
shared/media_archive/templates/imagekit/admin/selectable_thumbnail.html

@ -1,3 +1 @@
{% if thumbnail %}
<img src="{{ thumbnail.url }}">
{% endif %}
{% if thumbnail %}<img src="{{ thumbnail }}">{% endif %}

Loading…
Cancel
Save