S
S
Sergey Nizhny Novgorod2016-06-21 06:31:41
Django
Sergey Nizhny Novgorod, 2016-06-21 06:31:41

How to save thumbnails when uploading an image?

Hello.
Task:
When uploading an avatar, pass the image through the easy_thumbnails package and save the already cropped icon to the database. I use easy_thumbnails because it has a pretty cool option to select the most "interesting" part of the photo.
The code turns out to be something like:
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)

And I get an error that: If
object is not a FieldFile or Thumbnailer instance, the relative name must be provided fine.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
S
Sergey Nizhny Novgorod, 2016-06-22
@Terras

How to take an image from the ImageFiled field when loading, take a thumbnail from it and save only the thumbnail to the database
1) Install easy-thumnails
2) Create a regular model (no extensions and other garbage):

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

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

4) Making a view:
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)

As a result, we load any photo that Pillow can process, cut out the Thumbnails we need from it and save it to the model.
In case of an error, I just return the base page, you can write your own error handlers.

O
Oscar Django, 2016-06-21
@winordie

Let's look at the code again:

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)

Try this
avatar = get_thumbnailer(avatar, relative_name=avatar.name)

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question