I am trying to have a form to generate thumbnails from images that will be uploaded
I will be using sorl for the thumb generation and I am following the following documentation:
When I try to generate the thumbnail I get the error of
not enough values to unpack (expected 2, got 1)
I dont understand what I am doing wrong, in summary I upload the image and this get saved in my root directory, then im trying to create the thumb
Also is there a way to void saving this original image in the root? I am planning to send both Image and thumb to google cloud storage
My forms.py:
from django import forms
class FileFieldForm(forms.Form):
file_field = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True}))
My html file: upload.html
<html>
<head></head>
<body>
<h3>Read File Content</h3>
<form enctype="multipart/form-data" action="" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Save">
</form>
</body>
</html>
My views.py looks like:
from sorl.thumbnail import ImageField, get_thumbnail
from .forms import FileFieldForm
class FileFieldView(FormView):
form_class = FileFieldForm
template_name = 'app_workflow/upload.html' # Replace with your template.
success_url = '/photo' # Replace with your URL or reverse().
def post(self, request, *args, **kwargs):
form_class = self.get_form_class()
form = self.get_form(form_class)
files = request.FILES.getlist('file_field')
if form.is_valid():
for f in files:
with open(f.name, 'wb+') as destination:
for chunk in f.chunks():
destination.write(chunk)
im = get_thumbnail(f.name, '100x100', crop='center', quality=99)
return self.form_valid(form)
else:
return self.form_invalid(form)
As you have said in the question, you do not want to store in root and generate thumbnail. Then I would suggest something like this:
from PIL import Image
class FileFieldView(FormView):
form_class = FileFieldForm
template_name = 'app_workflow/upload.html' # Replace with your template.
success_url = '/photo' # Replace with your URL or reverse().
def form_valid(self, *args, **kwargs):
img_size = (100, 100)
files = self.request.FILES.getlist('file_field')
for f in files:
im = Image.open(f)
im.thumbnail(img_size)
# your thumbnail image is in memory now
# you can now store it in your model and use django-storages to upload it to gcloud
return super().form_valid(*args, **kwargs)
Here I am not storing images and directly loading it in the PIL.Image
module to generate thumbnails. You can use django-storages
to upload data from FileField to gcloud.
Then you can change the code like this:
for f in files:
for chunk in f.chunks():
destination.write(chunk)
im = Image.open(f)
im.thumbnail(img_size)
im.save('thumb_{}'.format(f.name))