Ответ 1
Во-первых, создайте файл widgets.py
в приложении. В моем примере я сделаю для вас класс AdminImageWidget
, который расширяет AdminFileWidget
. По сути, я хочу, чтобы поле загрузки изображения показывало текущее загруженное изображение в теге <img src="" />
вместо того, чтобы просто выводить путь к файлу.
Поместите следующий класс в ваш файл widgets.py
:
from django.contrib.admin.widgets import AdminFileWidget
from django.utils.translation import ugettext as _
from django.utils.safestring import mark_safe
import os
import Image
class AdminImageWidget(AdminFileWidget):
def render(self, name, value, attrs=None):
output = []
if value and getattr(value, "url", None):
image_url = value.url
file_name=str(value)
# defining the size
size='100x100'
x, y = [int(x) for x in size.split('x')]
try :
# defining the filename and the miniature filename
filehead, filetail = os.path.split(value.path)
basename, format = os.path.splitext(filetail)
miniature = basename + '_' + size + format
filename = value.path
miniature_filename = os.path.join(filehead, miniature)
filehead, filetail = os.path.split(value.url)
miniature_url = filehead + '/' + miniature
# make sure that the thumbnail is a version of the current original sized image
if os.path.exists(miniature_filename) and os.path.getmtime(filename) > os.path.getmtime(miniature_filename):
os.unlink(miniature_filename)
# if the image wasn't already resized, resize it
if not os.path.exists(miniature_filename):
image = Image.open(filename)
image.thumbnail([x, y], Image.ANTIALIAS)
try:
image.save(miniature_filename, image.format, quality=100, optimize=1)
except:
image.save(miniature_filename, image.format, quality=100)
output.append(u' <div><a href="%s" target="_blank"><img src="%s" alt="%s" /></a></div> %s ' % \
(miniature_url, miniature_url, miniature_filename, _('Change:')))
except:
pass
output.append(super(AdminFileWidget, self).render(name, value, attrs))
return mark_safe(u''.join(output))
Хорошо, так что происходит здесь?
- Я импортирую существующий виджет (вы можете начинать с нуля, но, вероятно, возможно расширить ClearableFileInput, если это то, с чего вы начинаете)
- Я хочу изменить выход/представление виджета, а не базовую логику. Таким образом, я переопределяю функцию виджета
render
. - в функции рендеринга Я строю вывод, который я хочу в качестве массива
output = []
, вам не нужно это делать, но он сохраняет некоторую конкатенацию. 3 ключевых строки:-
output.append(u' <div><a href="%s" target="_blank"><img src="%s" alt="%s" /></a></div> %s ' % (miniature_url, miniature_url, miniature_filename, _('Change:')))
Добавляет тег img на выход -
output.append(super(AdminFileWidget, self).render(name, value, attrs))
добавляет родительский вывод в мой виджет -
return mark_safe(u''.join(output))
соединяет мой выходной массив с пустыми строками И освобождает его от экранирования перед отображением
-
Как это использовать?
class SomeModelForm(forms.ModelForm):
"""Author Form"""
photo = forms.ImageField(
widget = AdminImageWidget()
)
class Meta:
model = SomeModel
ИЛИ
class SomeModelForm(forms.ModelForm):
"""Author Form"""
class Meta:
model = SomeModel
widgets = {'photo' : AdminImageWidget(),}
Что дает нам: