You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

272 lines
8.1 KiB

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, strip_tags
from django.utils.translation import gettext_lazy as _
from .conf import USE_TRANSLATABLE_FIELDS
from .forms import MediaCategoryAdminForm
from . import admin_actions, mixins, models
if USE_TRANSLATABLE_FIELDS:
from shared.multilingual.utils import i18n_fields, lang_suffix
else:
def i18n_fields(field_name, languages=None):
return [field_name]
def lang_suffix(language_code=None, 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):
"""
Customization of ChoicesFilterSpec which sorts in the user-expected format.
my_model_field.category_filter = True
"""
template = "media_archive/admin/select_filter.html"
def __init__(self, f, request, params, model, model_admin,
field_path=None):
super(CategoryFieldListFilter, self).__init__(
f, request, params, model, model_admin, field_path)
# Restrict results to categories which are actually in use:
if DJANGO_VERSION < (1, 8):
related_model = f.related.parent_model
related_name = f.related.var_name
elif DJANGO_VERSION < (2, 0):
related_model = f.rel.to
related_name = f.related_query_name()
else:
related_model = f.remote_field.model
related_name = f.related_query_name()
self.lookup_choices = sorted(
[
(i.pk, '%s (%s)' % (i, i._related_count))
for i in related_model.objects.annotate(
_related_count=Count(related_name)
).exclude(_related_count=0)
],
key=lambda i: i[1],
)
def choices(self, cl):
yield {
'selected': self.lookup_val is None,
'query_string': cl.get_query_string({}, [self.lookup_kwarg]),
'display': _('All')
}
for pk, title in self.lookup_choices:
yield {
'selected': pk == int(self.lookup_val or '0'),
'query_string': cl.get_query_string({self.lookup_kwarg: pk}),
'display': mark_safe(smart_text(title))
}
FieldListFilter.register(
lambda f: getattr(f, 'category_filter', False),
CategoryFieldListFilter,
take_priority=True)
@admin.register(models.MediaCategory)
class MediaCategoryAdmin(admin.ModelAdmin):
form = MediaCategoryAdminForm
list_display = ['path']
list_filter = ['parent']
list_per_page = 25
search_fields = ['name']
prepopulated_fields = {'slug': ('name',)}
raw_id_fields = ['parent']
def image_thumbnail_image(obj):
# TODO Return default placeholder image instead of None
return obj.image.thumbnail
@admin.register(models.MediaRole)
class MediaRoleAdmin(admin.ModelAdmin):
list_display = i18n_fields('name')
class MediaAdminBase(admin_actions.MediaBaseActionsMixin, mixins.DropUploadAdminMixin, admin.ModelAdmin):
list_display = ['is_public', 'admin_thumbnail', 'get_name_display',
'get_categories_display',
'modified'] # , 'created']
list_display_links = ('admin_thumbnail', 'get_name_display')
# list_editable = ['is_public']
list_per_page = 25
list_filter = ['is_public', 'categories', 'role']
search_fields = [
*i18n_fields('name'),
'slug',
*i18n_fields('caption'),
*i18n_fields('credits'),
*i18n_fields('copyright'),
]
date_hierarchy = 'modified'
ordering = ['-modified']
fieldsets = (
(None, {
'fields': [
*i18n_fields('caption'),
*i18n_fields('name'),
('file', 'image_ppoi'),
(
'is_public',
'role',
),
]}),
(_("Bildnachweise"), {
'fields': [
*i18n_fields('credits'),
*i18n_fields('copyright'),
]}),
(_("Verwaltung"), {
'classes': ['collapse'],
'fields': [
'categories',
]}),
)
filter_horizontal = ['categories']
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>{name}{caption}",
categories=", ".join([str(p) for p in obj.categories.all()]),
name=str(obj),
caption=caption,
)
get_name_display.short_description = _("Name")
get_name_display.admin_order_field = lang_suffix(fieldname='name')
def get_categories_display(self, obj):
return mark_safe("<br>".join([str(c) for c in obj.categories.all()]))
get_categories_display.short_description = _("Arbeitsmappen")
get_categories_display.admin_order_field = 'categories__name'
@admin.register(models.Image)
class ImageAdmin(MediaAdminBase):
actions = [
admin_actions.assign_category,
'change_is_public_action',
admin_actions.add_images_to_gallery,
]
@admin.register(models.Download)
class DownloadAdmin(MediaAdminBase):
list_display = ['is_public', '__str__']
list_display_links = ['__str__']
actions = [
admin_actions.assign_category,
'change_is_public_action',
]
class ImageGalleryRelInline(admin.TabularInline):
model = models.ImageGalleryRel
fields = ['admin_thumbnail', 'image', 'position']
readonly_fields = ['admin_thumbnail']
raw_id_fields = ['image']
extra = 0
verbose_name = _("Bild")
verbose_name_plural = _("Bilder")
admin_thumbnail = AdminThumbnail()
admin_thumbnail.short_description = _("Foto")
@admin.register(models.Gallery)
class GalleryAdmin(admin.ModelAdmin):
list_display = ('is_public', 'name', 'get_image_count')
list_display_links = ['name']
list_filter = ['is_public']
search_fields = [
*i18n_fields('name'),
'slug',
*i18n_fields('caption'),
*i18n_fields('credits'),
]
fieldsets = (
(None, {
'fields': [
'is_public',
*i18n_fields('name'),
'slug',
]}),
(_("Texte"), {
'fields': [
*i18n_fields('caption'),
*i18n_fields('credits'),
]}),
(_("Weiteres"), {
'classes': ['collapse'],
'fields': [
'order_index',
]}),
)
prepopulated_fields = {
'slug': [i18n_fields('name')[0]],
}
inlines = [ImageGalleryRelInline]
def get_image_count(self, obj):
return obj.images.count()
get_image_count.short_description = _("Bilder")