Задать вопрос

Как сохранить thumbnails при загрузке изображения?

Всем привет.

Задача:

При загрузке аватара пропустить изображение через пакет easy_thumbnails и уже обрезанную иконку сохранить в базу. Использую easy_thumbnails, так как там достаточно прикольная опция выбора самого "интересного" участка фотографии.

Код получается, что-то типа:

settings.py

THUMBNAIL_ALIASES = {
    '': {
        'avatar': {'size': (128, 128), 'crop': True},
    },
}


views.py

def update_profile(request, add_id):
    token = {}
    token.update(csrf(request))
    if request.user.is_authenticated():
        current_user = request.user
        if request.POST:
            # profilepage = Profile.objects.get(id = add_id)
            form = Profile_Form(request.POST or None, request.FILES or None)
            if form.is_valid():
                avatar = form.cleaned_data['avatar']
                avatar = get_thumbnailer(avatar)['avatar']
                myself = form.cleaned_data['myself']
                myoffer = form.cleaned_data['myoffer']
                profile_obj = Profile(user=current_user, avatar=avatar, myself=myself, myoffer = myoffer)
                profile_obj.save()
                return redirect('/profile'+ add_id, token)
            else:
                return redirect('/profile'+ add_id, token)
        else:
            return redirect('/profile'+ add_id, token)
    else:
        return redirect('/profile'+ add_id, token)


И получаю ошибку, что:

If object is not a FieldFile or Thumbnailer instance, the relative name must be provided

Если верить документации, самый низ: easy-thumbnails.readthedocs.io/en/2.1/usage/#overview то я делаю, все нормально.
  • Вопрос задан
  • 617 просмотров
Подписаться 2 Оценить Комментировать
Решения вопроса 1
Terras
@Terras Автор вопроса
Как при загрузке из поля ImageFiled взять изображение, взять из него thumbnail и сохранить в базу только thumbnail

1) Устанавливаем easy-thumnails

2) Создаем обычную модель (никаких расширений и прочей фигни):

class Profile(models.Model):    
    avatar = models.ImageField(upload_to='', blank=True, null=True, help_text="Идеальный размер 150 на 150 пикселей", verbose_name="Аватар юзера")


3) Делаем обычную django форму:

class Profile_Form(forms.Form):
    avatar = forms.ImageField(label='Загрузить Аватар', required=False)


4) Делаем вьюшку:

from thumbnails import get_thumbnail

def update_profile(request, add_id):
    token = {}
    token.update(csrf(request))
    if request.user.is_authenticated():
        current_user = request.user
        if request.POST:
            form = Profile_Form(request.POST or None, request.FILES or None)
            if form.is_valid():

                avatar = form.cleaned_data['avatar']

                options = {'size': (200, 200), 'crop': True}
                thumb_url = get_thumbnailer(avatar, relative_name='avatar').get_thumbnail(options).url
                
                profile_obj = Profile(avatar=thumb_url)
                profile_obj.save()

                return redirect('/profile'+ add_id, token)
            else:
                return redirect('/profile'+ add_id, token)
        else:
            return redirect('/profile'+ add_id, token)
    else:
        return redirect('/profile'+ add_id, token)


В итоге, мы загружаем любую фотку, которую может обработать Pillow, вырезаем из неё нужный нам Thumbnails и сохраняем его в модель.

В случае ошибки я просто возвращаю базовую страницу, вы можете написать свои обработчики ошибки.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
winordie
@winordie
Лучшая документация -- исходники
И снова таки посмотрим код:
def get_thumbnailer(obj, relative_name=None):
    if hasattr(obj, 'easy_thumbnails_thumbnailer'):
        return obj.easy_thumbnails_thumbnailer
    if isinstance(obj, Thumbnailer):
        return obj
    elif isinstance(obj, FieldFile):
        if not relative_name:
            relative_name = obj.name
        return ThumbnailerFieldFile(obj.instance, obj.field, relative_name)

    source_storage = None

    if isinstance(obj, six.string_types):
        relative_name = obj
        obj = None

    if not relative_name:
        raise ValueError(
            "If object is not a FieldFile or Thumbnailer instance, the "
            "relative name must be provided")

    if isinstance(obj, File):
        obj = obj.file
    if isinstance(obj, Storage) or obj == default_storage:
        source_storage = obj
        obj = None

    return Thumbnailer(
        file=obj, name=relative_name, source_storage=source_storage,
        remote_source=obj is not None)

Попробуй так
avatar = get_thumbnailer(avatar, relative_name=avatar.name)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы