Tue 12 Feb 2008
Миниатюрки картинок в админке Django
Posted by Alrond | Tags: Django :
Martin Mahner написал небольшой туториал о том, как в админке django добавить миниатюрки картинок (Thumbnails). Здесь я привожу ее перевод.
Update 03.Apr.08
Мини-модель
Рассмотрим модель с четырьмя полями: название картинки, описание к ней, датой публикации и самой картинкой, в нашем случае models.ImageField, которая управляет загрузкой и путем к ней.

Ничего особенного. Наша цель на этой странице показать картинку в маленьком варианте. Вы, навярняка, уже подумали об атрибуте list_display. Здесь можно решить, какие поля задавать на странице. Сейчас это: название, картинка (имя), описание и дата открытия.
Этот список естественно не ограничен данной моделью, можно определять свои методы модели.
Чтобы включить картинку в админке, достаточно простого метода, который соединяет название картинки (например: /bilder/test.jpg) с вашим медиа-URL (см. settings.py, пример: /media/) и возвращает как результат. Как пример: /media/bilder/test.jpg/
Кто работает под Windows, знает, что папки разделены одним "\" , в этом случае поменяем еще все "\" на "/".
Дополнительная мета-информация short_description для этого метода описывает название столбца, а allow_tags дает Django понять, что в этом столбце разрешен HTML.

Слишком большая картинка!
Выглядит уже неплохо. Единственное, что сразу бросается в глаза, первая картинка слишком большая. Кто сохраняет в модель большие картинки - размером 1600x1200px и выше, кроме нее ничего больше не увидит. Здесь должен быть применен фильтр.
Для этого примера воспользуемся фильтром Michelt-а из Djangosnippets. Вам необходима Python Imaging Library (PIL), которую можно просто инсталировать в Debian/Ubtuntu при помощи запроса:
Еще один трюк, что картинки уменьшатся посредством AntiAliasing, и тем самым исчезнет некрасивая окантовка.
Измените Code картинки:

Еще раз целая модель:
Update 03.Apr.08
Отвечая на вопрос Дмитрия, написал небольшой скрипт preview.js (частично функциональность спер у jQuery), который подключается в админку так:
Update 03.Apr.08
Мини-модель
Рассмотрим модель с четырьмя полями: название картинки, описание к ней, датой публикации и самой картинкой, в нашем случае models.ImageField, которая управляет загрузкой и путем к ней.
# -*- coding: utf-8 -*-
from django.db import models
class GalleryImage(models.Model):
title = models.CharField('Titel', max_length=250)
description = models.TextField('Beschreibung', blank=True)
pub_date = models.DateTimeField('Hinzugefügt', auto_now_add=True)
image = models.ImageField('Bild', upload_to='bilder/')
class Admin:
list_display = (
'title',
'image',
'description',
'pub_date',
)
def __unicode__(self):
return str(self.id)
Ваша модель галереи скорее всего будет выглядеть похоже. С парой дат и картинок это выглядит так:
Ничего особенного. Наша цель на этой странице показать картинку в маленьком варианте. Вы, навярняка, уже подумали об атрибуте list_display. Здесь можно решить, какие поля задавать на странице. Сейчас это: название, картинка (имя), описание и дата открытия.
Этот список естественно не ограничен данной моделью, можно определять свои методы модели.
Чтобы включить картинку в админке, достаточно простого метода, который соединяет название картинки (например: /bilder/test.jpg) с вашим медиа-URL (см. settings.py, пример: /media/) и возвращает как результат. Как пример: /media/bilder/test.jpg/
Кто работает под Windows, знает, что папки разделены одним "\" , в этом случае поменяем еще все "\" на "/".
Дополнительная мета-информация short_description для этого метода описывает название столбца, а allow_tags дает Django понять, что в этом столбце разрешен HTML.
import os
from django.conf import settings
from django.db import models
class GalleryImage(models.Model):
# ...
class Admin:
list_display = (
'title',
'image',
# Die Model-Methode preview_image_url()
'preview_image_url',
'description',
'pub_date',
)
def preview_image_url(self):
image_path = os.path.join(settings.MEDIA_URL, self.image)
image_path = image_path.replace('\\','/') # Windows-Fix
return '<a href="'+ str(self.id) +'/"><img
src="'+ str(image_path) +'"/></a>'
preview_image_url.short_description = 'Thumbnail'
preview_image_url.allow_tags = True
Пары строк хватит и мы уже имеем к каждой записи маленькую картинку:
Слишком большая картинка!
Выглядит уже неплохо. Единственное, что сразу бросается в глаза, первая картинка слишком большая. Кто сохраняет в модель большие картинки - размером 1600x1200px и выше, кроме нее ничего больше не увидит. Здесь должен быть применен фильтр.
Для этого примера воспользуемся фильтром Michelt-а из Djangosnippets. Вам необходима Python Imaging Library (PIL), которую можно просто инсталировать в Debian/Ubtuntu при помощи запроса:
apt-get install python-imagingФильтр действует очень просто:
- ему передается URL картинки из ImageField,
- он выводит маленькую картинку переменного размера,
- сохраняет картинку в ту же папку как имя_ШИРИНАxВЫСОТА.jpg,
- и возврашает новый URL маленькой картинки.
Еще один трюк, что картинки уменьшатся посредством AntiAliasing, и тем самым исчезнет некрасивая окантовка.
Измените Code картинки:
image.thumbnail([x, y]) # генерирует 200x200 thumbnail # Заменить на image.thumbnail([x, y], Image.ANTIALIAS) # генерирует 200x200 thumbnailИтак, улучшенная функция просмотра картинки в модели выглядит следующим образом:
# Die Thumbnail-Funktion liegt in einer Datei "utils.py" im
# selben Verzeichnis wie die Model-Definition
from my_project.gallery.utils import thumbnail
class GalleryImage(models.Model):
# ...
def preview_image_url(self):
image_path = thumbnail(self.image, '60x60') # создается миниатюра
image_path = image_path.replace('\\','/') # Windows-Fix
return '<a href="'+ str(self.id) +'/"><img src="'+
str(image_path) +'"/></a>'
Что получилось? Слишком большой SpongeBob Schwammkopf уменьшился до нормальных размеров!
Еще раз целая модель:
# -*- coding: utf-8 -*-
from django.db import models
from my_project.gallery.utils import thumbnail
class GalleryImage(models.Model):
title = models.CharField('Titel', max_length=250)
description = models.TextField('Beschreibung', blank=True)
pub_date = models.DateTimeField('Hinzugefügt', auto_now_add=True)
image = models.ImageField('Bild', upload_to='bilder/')
class Admin:
list_display = (
'title',
'image',
'preview_image_url',
'description',
'pub_date',
)
def preview_image_url(self):
image_path = thumbnail(self.image, '60x60')
image_path = image_path.replace('\\','/') # Windows-Fix
return '<a href="'+ str(self.id) +'/"><img src="'+
str(image_path) +'"/></a>'
preview_image_url.short_description = 'Thumbnail'
preview_image_url.allow_tags = True
def __unicode__(self):
return str(self.id)
Продолжение следует...Update 03.Apr.08
Отвечая на вопрос Дмитрия, написал небольшой скрипт preview.js (частично функциональность спер у jQuery), который подключается в админку так:
class Admin:
...
js = ('preview.js',)
В самом скрипте надо изменить переменные ADDON на требуемый размер миниатюрки и MEDIA_URL как в settings.py
English
Deutsch
Русский
(7 votes, average: 4.6 out of 5)
April 2nd, 2008 at 9:42 a.m.
А как можно добавить подобное поле на странице редактирования объекта?
April 3rd, 2008 at 6:12 p.m.
Ответил апдейтом в конце поста
April 11th, 2008 at 1:52 p.m.
Спасибо большое! : )
April 24th, 2008 at 1:31 p.m.
От себя позволю добавить, что функция bindReady в preview.js для IE6.0 не вполне работа способна. Вот поправленный вариант bindReady:
function bindReady(){
if ( readyBound ) return;
readyBound = true;
if (!browser.opera)
if (document.addEventListener)
document.addEventListener( "DOMContentLoaded", ready, false );
else if (document.attachEvent)
document.attachEvent( "DOMContentLoaded", ready );
if ( browser.msie && window == top ) (function(){
if (isReady) return;
try {
document.documentElement.doScroll("left");
} catch( error ) {
setTimeout( arguments.callee, 0 );
return;
}
ready();
}) ();
if (document.addEventListener)
document.addEventListener("load", ready, false );
else if (document.attachEvent)
document.attachEvent( "load", ready );
}
А так спасибо за статью сейчас данный вариант пытаюсь прикрутить к manytomany