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

1
shared/media_archive/conf.py

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

73
shared/media_archive/models.py

@ -1,14 +1,15 @@
import logging import logging
import posixpath import posixpath
import re import re
from functools import partial
from django.db import models from django.db import models
from django.utils.html import strip_tags from django.utils.html import strip_tags
from django.utils.text import Truncator
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from imagefield.fields import ImageField, PPOIField from imagefield.fields import ImageField, PPOIField
from imagekit.models import ImageSpecField from shared.utils.text import html_to_text, sanitized_html
from imagekit.processors import Adjust, Thumbnail, ResizeToFit, ResizeToFill
from shared.utils.models.slugs import DowngradingSlugField, slugify from shared.utils.models.slugs import DowngradingSlugField, slugify
from .conf import UPLOAD_TO, USE_TRANSLATABLE_FIELDS from .conf import UPLOAD_TO, USE_TRANSLATABLE_FIELDS
@ -34,7 +35,7 @@ class MediaCategoryManager(models.Manager):
class MediaCategory(models.Model): class MediaCategory(models.Model):
name = models.CharField(_("name"), max_length=200) name = models.CharField(_("name"), blank=True, max_length=200)
parent = models.ForeignKey( parent = models.ForeignKey(
'self', blank=True, null=True, 'self', blank=True, null=True,
on_delete=models.CASCADE, on_delete=models.CASCADE,
@ -78,7 +79,8 @@ class Gallery(models.Model):
help_text=_("Publicly visible name.")) help_text=_("Publicly visible name."))
slug = models.SlugField(_("Slug"), null=True, blank=True) slug = models.SlugField(_("Slug"), null=True, blank=True)
credits = TranslatableCharField(_("Credits"), null=True, blank=True, max_length=500) 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) is_public = models.BooleanField(_("Active"), default=False)
order_index = models.PositiveIntegerField(_("Order Index"), default=0) order_index = models.PositiveIntegerField(_("Order Index"), default=0)
# background_color = models.ForeignKey('site_pages.Color', on_delete=models.PROTECT, # 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) name = TranslatableCharField(_("name"), max_length=200)
class Meta: class Meta:
verbose_name = _("Bild-Typ") verbose_name = _("Art")
verbose_name_plural = _("Bild-Typen") verbose_name_plural = _("Arten")
ordering = i18n_fields('name') ordering = i18n_fields('name')
def __str__(self): def __str__(self):
@ -194,7 +196,9 @@ class MediaBase(DeleteOldFileMixin, models.Model):
verbose_name=_("Typ"), verbose_name=_("Typ"),
null=True, blank=True) null=True, blank=True)
name = TranslatableCharField(_("Name"), max_length=200, 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) credits = TranslatableCharField(_("Credits"), max_length=500, null=True, blank=True)
copyright = TranslatableCharField(_('Rechteinhaber/in'), max_length=2000, 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) return self.name or strip_tags(self.caption) or posixpath.basename(self.file.name)
def save(self, *args, **kwargs): 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: if self.file:
try: try:
self.file_size = self.file.size self.file_size = self.file.size
@ -221,14 +230,6 @@ class MediaBase(DeleteOldFileMixin, models.Model):
class Image(MediaBase): 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( file = ImageField(
_("image"), _("image"),
max_length=200, max_length=200,
@ -238,43 +239,11 @@ class Image(MediaBase):
ppoi_field="image_ppoi", ppoi_field="image_ppoi",
blank=True, blank=True,
) )
image_width = models.PositiveIntegerField(
logo_image = ImageSpecField(source='file', _("image width"), blank=True, null=True, editable=False)
processors=[ResizeToFit(150, 150)]) image_height = models.PositiveIntegerField(
_("image height"), blank=True, null=True, editable=False)
thumbnail = ImageSpecField(source='file', image_ppoi = PPOIField(_("primary point of interest"))
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
type = 'image' type = 'image'

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

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

Loading…
Cancel
Save