mod: админка (06) ImageAdmin (07) minor3
This commit is contained in:
@@ -22,7 +22,7 @@ class TbImageAdminForm(forms.ModelForm):
|
|||||||
(default_alt_text и default_caption), которые не хранятся в TbImage, но есть в filer_image
|
(default_alt_text и default_caption), которые не хранятся в TbImage, но есть в filer_image
|
||||||
"""
|
"""
|
||||||
# Виртуальные поля для заполнения метаданных filer_image
|
# Виртуальные поля для заполнения метаданных filer_image
|
||||||
filer_alt_text = forms.CharField(
|
alt_text = forms.CharField(
|
||||||
max_length=255,
|
max_length=255,
|
||||||
required=False,
|
required=False,
|
||||||
widget=forms.TextInput(attrs={
|
widget=forms.TextInput(attrs={
|
||||||
@@ -32,7 +32,7 @@ class TbImageAdminForm(forms.ModelForm):
|
|||||||
help_text='Текст для alt-атрибута картинки <tt><img alt="" .../></tt>.'
|
help_text='Текст для alt-атрибута картинки <tt><img alt="" .../></tt>.'
|
||||||
' Будет сохранён в filer_image.default_alt_text'
|
' Будет сохранён в filer_image.default_alt_text'
|
||||||
)
|
)
|
||||||
filer_caption = forms.CharField(
|
title_text = forms.CharField(
|
||||||
max_length=255,
|
max_length=255,
|
||||||
required=False,
|
required=False,
|
||||||
widget=forms.TextInput(attrs={
|
widget=forms.TextInput(attrs={
|
||||||
@@ -42,7 +42,7 @@ class TbImageAdminForm(forms.ModelForm):
|
|||||||
help_text='Текст для title-атрибута картинки <tt><img title="" .../></tt>.'
|
help_text='Текст для title-атрибута картинки <tt><img title="" .../></tt>.'
|
||||||
' Будет сохранён в filer_image.default_caption'
|
' Будет сохранён в filer_image.default_caption'
|
||||||
)
|
)
|
||||||
filer_copyright = forms.CharField(
|
copyright_text = forms.CharField(
|
||||||
max_length=255,
|
max_length=255,
|
||||||
required=False,
|
required=False,
|
||||||
widget=forms.TextInput(attrs={
|
widget=forms.TextInput(attrs={
|
||||||
@@ -72,21 +72,24 @@ class TbImageAdminForm(forms.ModelForm):
|
|||||||
# Если редактируем существующую запись, получаем текущие значения из filer
|
# Если редактируем существующую запись, получаем текущие значения из filer
|
||||||
if self.instance and self.instance.pk and hasattr(self.instance, 'image') and self.instance.image:
|
if self.instance and self.instance.pk and hasattr(self.instance, 'image') and self.instance.image:
|
||||||
try:
|
try:
|
||||||
|
# Получаем связанные данные из filer_image
|
||||||
filer_image = self.instance.image
|
filer_image = self.instance.image
|
||||||
# Получаем текущие значения из filer и заполняем виртуальные поля
|
|
||||||
self.fields['filer_alt_text'].initial = filer_image.default_alt_text or ''
|
# Устанавливаем значения из filer в виртуальные поля
|
||||||
self.fields['filer_caption'].initial = filer_image.default_caption or ''
|
self.fields['alt_text'].initial = filer_image.default_alt_text or ''
|
||||||
self.fields['filer_copyright'].initial = filer_image.author or ''
|
self.fields['title_text'].initial = filer_image.default_caption or ''
|
||||||
# Активация CodeMirror и устанавливаем CSS-классы для виртуальных полей
|
self.fields['copyright_text'].initial = filer_image.author or ''
|
||||||
self.fields['filer_alt_text'].widget = Textarea(attrs={
|
|
||||||
|
# Активируем CodeMirror и устанавливаем CSS-классы для виртуальных полей
|
||||||
|
self.fields['alt_text'].widget = Textarea(attrs={
|
||||||
**codemirror_attrs,
|
**codemirror_attrs,
|
||||||
'class': 'codemirror-width-m',
|
'class': 'codemirror-width-m',
|
||||||
})
|
})
|
||||||
self.fields['filer_caption'].widget = Textarea(attrs={
|
self.fields['title_text'].widget = Textarea(attrs={
|
||||||
**codemirror_attrs,
|
**codemirror_attrs,
|
||||||
'class': 'codemirror-width-m',
|
'class': 'codemirror-width-m',
|
||||||
})
|
})
|
||||||
self.fields['filer_copyright'].widget = Textarea(attrs={
|
self.fields['copyright_text'].widget = Textarea(attrs={
|
||||||
**codemirror_attrs,
|
**codemirror_attrs,
|
||||||
'class': 'codemirror-width-m',
|
'class': 'codemirror-width-m',
|
||||||
})
|
})
|
||||||
@@ -94,22 +97,18 @@ class TbImageAdminForm(forms.ModelForm):
|
|||||||
# Если ошибка при получении filer_image, просто оставляем пустые значения
|
# Если ошибка при получении filer_image, просто оставляем пустые значения
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# s_img_src_url - поле URL источника (длинная строка)
|
# Активируем CodeMirror и устанавливаем классы для реальных полей
|
||||||
self.fields['s_img_src_url'].widget = Textarea(attrs={
|
self.fields['s_img_src_url'].widget = Textarea(attrs={
|
||||||
|
**codemirror_attrs,
|
||||||
'class': 'codemirror-width-xl',
|
'class': 'codemirror-width-xl',
|
||||||
**codemirror_attrs,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
# i_img_sort - поле сортировки (до четырех цифр)
|
|
||||||
self.fields['i_img_sort'].widget = Textarea(attrs={
|
self.fields['i_img_sort'].widget = Textarea(attrs={
|
||||||
'class': 'codemirror-width-s codemirror-no-lines',
|
|
||||||
**codemirror_attrs,
|
**codemirror_attrs,
|
||||||
|
'class': 'codemirror-width-s codemirror-no-lines',
|
||||||
})
|
})
|
||||||
|
|
||||||
# f_img_confidence_score - поле confidence score (число с плавающей точкой)
|
|
||||||
self.fields['f_img_confidence_score'].widget = Textarea(attrs={
|
self.fields['f_img_confidence_score'].widget = Textarea(attrs={
|
||||||
'class': 'codemirror-width-s codemirror-no-lines',
|
|
||||||
**codemirror_attrs,
|
**codemirror_attrs,
|
||||||
|
'class': 'codemirror-width-s codemirror-no-lines',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@@ -129,14 +128,14 @@ class ImageAdmin(admin.ModelAdmin):
|
|||||||
}
|
}
|
||||||
js = (
|
js = (
|
||||||
'codemirror/editor.js', # Основной CodeMirror
|
'codemirror/editor.js', # Основной CodeMirror
|
||||||
'codemirror/codemirror-patch.js', # Патч для управления высотой/шириной
|
'codemirror/codemirror-patch.js', # Патч для управления высотой/шириной
|
||||||
)
|
)
|
||||||
|
|
||||||
list_display = ('id', 'image_thumbnail', 'image', '_display_filer_alt_text', 'i_img_sort', 't_img_created')
|
list_display = ('id', 'image_thumbnail', 'image', '_display_alt_text', 'i_img_sort', 't_img_created')
|
||||||
list_display_links = ('id', 'image_thumbnail', 'image')
|
list_display_links = ('id', 'image_thumbnail', 'image')
|
||||||
list_filter = ('l_img_source', 'l_img_reality', 't_img_created')
|
list_filter = ('l_img_source', 'l_img_reality', 't_img_created')
|
||||||
ordering = ('image', 'i_img_sort')
|
ordering = ('image', 'i_img_sort')
|
||||||
readonly_fields = ('t_img_created', 't_img_updated', '_display_filer_alt_text', '_display_filer_caption')
|
readonly_fields = ('t_img_created', 't_img_updated', '_display_alt_text', '_display_title_text')
|
||||||
|
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
('Изображение', {
|
('Изображение', {
|
||||||
@@ -145,8 +144,8 @@ class ImageAdmin(admin.ModelAdmin):
|
|||||||
'description': 'Основные данные об изображении и источнике',
|
'description': 'Основные данные об изображении и источнике',
|
||||||
}),
|
}),
|
||||||
('Метаданные filer (SEO для картинок)', {
|
('Метаданные filer (SEO для картинок)', {
|
||||||
'fields': ('_display_filer_alt_text', '_display_filer_caption', 'filer_alt_text', 'filer_caption',
|
'fields': ('_display_alt_text', '_display_title_text', 'alt_text', 'title_text',
|
||||||
'filer_copyright'),
|
'copyright_text'),
|
||||||
'description': 'Редактируемые поля для заполнения ALT-, TITLE- и ©-текста в filer. Если не заполнить,'
|
'description': 'Редактируемые поля для заполнения ALT-, TITLE- и ©-текста в filer. Если не заполнить,'
|
||||||
' текущие значения останутся без изменений (и не будут заполнены при создании).',
|
' текущие значения останутся без изменений (и не будут заполнены при создании).',
|
||||||
# 'classes': ('collapse',),
|
# 'classes': ('collapse',),
|
||||||
@@ -192,7 +191,7 @@ class ImageAdmin(admin.ModelAdmin):
|
|||||||
# Установляем название столбца в админке
|
# Установляем название столбца в админке
|
||||||
image_thumbnail.short_description = 'Миниатюра (40x40)'
|
image_thumbnail.short_description = 'Миниатюра (40x40)'
|
||||||
|
|
||||||
def _display_filer_alt_text(self, obj):
|
def _display_alt_text(self, obj):
|
||||||
"""
|
"""
|
||||||
Display-метод для отображения текущего alt-текста в filer (read-only).
|
Display-метод для отображения текущего alt-текста в filer (read-only).
|
||||||
Показывает, какой текст сейчас установлен в filer_image.
|
Показывает, какой текст сейчас установлен в filer_image.
|
||||||
@@ -205,9 +204,9 @@ class ImageAdmin(admin.ModelAdmin):
|
|||||||
return '(ошибка при получении)'
|
return '(ошибка при получении)'
|
||||||
return '(новая запись, значение будет установлено после сохранения)'
|
return '(новая запись, значение будет установлено после сохранения)'
|
||||||
|
|
||||||
_display_filer_alt_text.short_description = 'ALT из filer'
|
_display_alt_text.short_description = 'ALT из filer'
|
||||||
|
|
||||||
def _display_filer_caption(self, obj):
|
def _display_title_text(self, obj):
|
||||||
"""
|
"""
|
||||||
Display-метод для отображения текущего caption в filer (read-only).
|
Display-метод для отображения текущего caption в filer (read-only).
|
||||||
Показывает, какой текст сейчас установлен в filer_image.
|
Показывает, какой текст сейчас установлен в filer_image.
|
||||||
@@ -220,13 +219,13 @@ class ImageAdmin(admin.ModelAdmin):
|
|||||||
return '(ошибка при получении)'
|
return '(ошибка при получении)'
|
||||||
return '(новая запись, значение будет установлено после сохранения)'
|
return '(новая запись, значение будет установлено после сохранения)'
|
||||||
|
|
||||||
_display_filer_caption.short_description = 'TITLE из filer'
|
_display_title_text.short_description = 'TITLE из filer'
|
||||||
|
|
||||||
def save_model(self, request, obj, form, change):
|
def save_model(self, request, obj, form, change):
|
||||||
"""
|
"""
|
||||||
Переопределяем save_model для обновления метаданных filer_image.
|
Переопределяем save_model для обновления метаданных filer_image.
|
||||||
|
|
||||||
Если пользователь заполнил виртуальные поля filer_alt_text или filer_caption,
|
Если пользователь заполнил виртуальные поля alt_text или title_text,
|
||||||
их значения сохраняются в соответствующие поля filer_image.
|
их значения сохраняются в соответствующие поля filer_image.
|
||||||
Если поля не заполнены, текущие значения в filer остаются без изменений.
|
Если поля не заполнены, текущие значения в filer остаются без изменений.
|
||||||
"""
|
"""
|
||||||
@@ -239,17 +238,17 @@ class ImageAdmin(admin.ModelAdmin):
|
|||||||
filer_image = obj.image
|
filer_image = obj.image
|
||||||
|
|
||||||
# Обновляем alt_text (ALT), если было заполнено в форме
|
# Обновляем alt_text (ALT), если было заполнено в форме
|
||||||
alt_text = form.cleaned_data.get('filer_alt_text', '').strip()
|
alt_text = form.cleaned_data.get('alt_text', '').strip()
|
||||||
if alt_text: # Если пользователь что-то ввел
|
if alt_text: # Если пользователь что-то ввел
|
||||||
filer_image.default_alt_text = alt_text
|
filer_image.default_alt_text = alt_text
|
||||||
|
|
||||||
# Обновляем caption (TITLE), если было заполнено в форме
|
# Обновляем caption (TITLE), если было заполнено в форме
|
||||||
caption = form.cleaned_data.get('filer_caption', '').strip()
|
caption = form.cleaned_data.get('title_text', '').strip()
|
||||||
if caption: # Если пользователь что-то ввел
|
if caption: # Если пользователь что-то ввел
|
||||||
filer_image.default_caption = caption
|
filer_image.default_caption = caption
|
||||||
|
|
||||||
# Обновляем author (copyrughight), если было заполнено в форме
|
# Обновляем author (copyrughight), если было заполнено в форме
|
||||||
author = form.cleaned_data.get('filer_copyright', '').strip()
|
author = form.cleaned_data.get('copyright_text', '').strip()
|
||||||
if author:
|
if author:
|
||||||
filer_image.author = author
|
filer_image.author = author
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user