使用PIL时,“ JpegImageFile”对象没有属性“ _committed”错误

我正在使用PIL压缩上传的图像(FileField).但是我遇到一个错误,我认为这是双重保存的问题? (保存我的图像,然后保存包括该图像的整个表单).我要在保存图像时执行commit = False,但似乎没有可能.这是我的代码:

...
if form_post.is_valid():
    instance = form_post.save(commit=False)
    instance.user = request.user

if instance.image:
    filename = instance.image
    instance.image = Image.open(instance.image)
    instance.image.thumbnail((220, 130), Image.ANTIALIAS)
    instance.image.save(filename, quality=60)

instance.save()

返回’JpegImageFile’对象的最后一行没有属性’_committed’错误(instance.save())

有人可以找出问题所在吗? -知道我该如何解决吗?

完整回溯:

File "/Users/zorgan/Desktop/app/lib/python3.5/site-packages/django/core/handlers/exception.py" in inner
  41.             response = get_response(request)

File "/Users/zorgan/Desktop/app/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response
  187.                 response = self.process_exception_by_middleware(e, request)

File "/Users/zorgan/Desktop/app/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response
  185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/Users/zorgan/Desktop/app/lib/python3.5/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
  23.                 return view_func(request, *args, **kwargs)

File "/Users/zorgan/Desktop/project/site/post/views.py" in post
  68.                 if uploaded_file_type(instance) is True:

File "/Users/zorgan/Desktop/project/site/functions/helper_functions.py" in uploaded_file_type
  12.     f = file.image.read(1024)

Exception Type: AttributeError at /post/
Exception Value: 'JpegImageFile' object has no attribute 'read'

完整型号:

class Post(models.Model):
    user = models.ForeignKey(User, blank=True, null=True)
    title = models.TextField(max_length=95)
    image = models.FileField(null=True, blank=True)

以及随附的PostForm:

class PostForm(forms.ModelForm):
    title = forms.TextInput(attrs={'placeholder': 'title'})

    class Meta:
        model = Post
        fields = [
            'user',
            'title',
            'image',
        ]

views.py

def post(request):    
    if request.user.is_authenticated():
        form_post = PostForm(request.POST or None, request.FILES or None)
        if form_post.is_valid():
            instance = form_post.save(commit=False)

            if instance.image:
                filename = instance.image
                instance.image = Image.open(instance.image)
                instance.image.thumbnail((220, 130), Image.ANTIALIAS)
                instance.image.save(filename, quality=60)

            instance.save()

            return HttpResponseRedirect('/home/')
        else:
            form_post = PostForm()

        context = {
            'form_post': form_post,
        }

        return render(request, 'post/post.html', context)
    else:
        return HttpResponseRedirect("/accounts/signup/")

下面的代码:

if instance.image:
    im = Image.open(instance.image)
    print("Filename:", im.filename) #doesn't print anything
    thumb = im.thumbnail((220, 130), Image.ANTIALIAS)
    thumb.save(im.filename, quality=60)

返回AttributeError:’NoneType’对象没有属性’save’.我相信这是因为im.filename不输出任何内容.知道为什么吗?

另一种方法:

if instance.image:
    im = Image.open(instance.image)
    thumb = im.thumbnail((220, 130), Image.ANTIALIAS)
    thumb_io = BytesIO()
    thumb.save(thumb_io, im.format, quality=60)
    instance.image.save(im.filename, ContentFile(thumb_io.get_value()), save=False)

还返回AttributeError:’NoneType’对象在此行上没有属性’save’:thumb.save(thumb_io,im.format,quality = 60).不知道为什么吗?

最佳答案
您必须将Django File对象的实例传递给FileField.save()才能更改文件字段的内容.它的工作方式与其他类型的模型字段有所不同.

FieldFile.save(name, content, save=True)

This method takes a filename and file contents and passes them to the
storage class for the field, then associates the stored file with the
model field. If you want to manually associate file data with
FileField instances on your model, the save() method is used to
persist that file data.

from PIL import Image
from django.core.files.base import ContentFile

if instance.image:
    im = Image.open(instance.image)
    im.thumbnail((220, 130), Image.ANTIALIAS)
    thumb_io = BytesIO()
    im.save(thumb_io, im.format, quality=60)
    instance.image.save(im.filename, ContentFile(thumb_io.get_value()), save=False)
instance.save()

但是,如果您不使用远程文件存储后端,则可以覆盖文件本身.该文件是在您调用form.save()时创建的.由于您使用相同的文件名和位置,因此您实际上不必触摸模型或告诉django您正在弄乱文件本身.

if instance.image:
    im = Image.open(instance.image)
    im.thumbnail((220, 130), Image.ANTIALIAS)
    im.save(im.filename, quality=60)

转载注明原文:使用PIL时,“ JpegImageFile”对象没有属性“ _committed”错误 - 代码日志