Django 1.11:在保存到Django模型之前水平翻转图像

时间:2017-05-18 20:45:38

标签: django

我正在执行此应用程序,其中我获取用户的图像,然后使用ImageOps库中的Pillow水平翻转它。为此,我制作了如上所示的模型:

from django.db import models


class ImageClient(models.Model):
    image = models.ImageField(null=False, blank=False)

我使用带有ImageField的html表单的enctype="multipart/form-data"制作了一个表单,在我看来,我做了以下内容:

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})
....

如您所见,当检查表单是否有效时,我打开表单的图像并水平翻转(使用ImageOps.mirror())然后保存。但我总是收到此错误'Image' object has no attribute '_committed'。我知道Image object来自Pillow,但我不明白这个错误。有人可以解释和/或解决这个错误吗?

1 个答案:

答案 0 :(得分:2)

引发错误是因为图像是PIL Image对象,而Django期待并需要自己的File对象。您可以将Image对象保存到绝对文件路径,然后引用它,但有更有效的方法herehere。以下是@ madzohan在后一个链接中对图像操作的回答:

# 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)

和views.py:

...
if form.is_valid():
    new_image = form.save()
    return redirect('img:detail', pk=new_image.id)