Reputation: 643
I'm doing this application where I take a user's image and then flip it horizontally using ImageOps
from the Pillow
library. To do so I made a model like above:
from django.db import models
class ImageClient(models.Model):
image = models.ImageField(null=False, blank=False)
I made a form using ImageField
with a html form with enctype="multipart/form-data"
and in my views I did the following:
from django.shortcuts import render, redirect
from .forms import ImageForm
from .models import ImageClient
from PIL import Image, ImageOps
def new(request):
"""
Returns mirror image from client.
"""
if request.method == 'POST':
form = ImageForm(request.POST, request.FILES)
if form.is_valid():
image = Image.open(form.cleaned_data['image'])
image = ImageOps.mirror(image)
form_image = ImageClient(image=image)
form_image.save()
return redirect('img:detail', pk=form_image.id)
else:
form = ImageForm()
return render(request, 'img/new_egami.html', {'form':form})
....
As you see, when a check if the form is valid, I open the form's image and flip it horizontally (using ImageOps.mirror()
) then I save it. But I always getting this error 'Image' object has no attribute '_committed'
. I know the Image object
is from Pillow, but I do not understand this error. Can someone explain and/or solve this error?
Upvotes: 0
Views: 395
Reputation: 962
The error is raised because the image is a PIL Image
object, whereas Django is expecting and requires its own File
object. You could save the Image object to an absolute file path and then refer to it, but there are more efficient ways here and here. Here is an adaptation of @madzohan's answer in the latter link for your image operation:
# models.py
from io import BytesIO
from django.core.files.base import ContentFile
from PIL import Image, ImageOps
class ImageClient(models.Model):
image = models.ImageField(null=False, blank=False, upload_to="image/path/")
def save(self, *args, **kwargs):
pil_image_obj = Image.open(self.image)
new_image = ImageOps.mirror(pil_image_obj)
new_image_io = BytesIO()
new_image.save(new_image_io, format='JPEG')
temp_name = self.image.name
self.image.delete(save=False)
self.image.save(
temp_name,
content=ContentFile(new_image_io.getvalue()),
save=False
)
super(ImageClient, self).save(*args, **kwargs)
and views.py:
...
if form.is_valid():
new_image = form.save()
return redirect('img:detail', pk=new_image.id)
Upvotes: 2