如何在 django 中正确创建 InMemoryUploadedFile 对象

rav*_*001 6 django io django-models python-imaging-library python-3.x

我正在使用 python 函数来调整 Django 中用户上传的图像的大小。我使用BytesIO()InMemoryUploadedFile()类将pillow对象转换为 DjangoUplodedFile并将其保存在模型中。这是我如何实例化InMemoryUploadedFile对象

from PIL import Image
import io
import PIL
import sys
from django.core.files.uploadedfile import InMemoryUploadedFile


def image_resize(image,basewidth):
    img_io = io.BytesIO()
    img = Image.open(image)
    percent = (basewidth / float(img.size[0]))
    hsize = int(float(img.size[1]) * percent)
    img = img.resize((basewidth, hsize),PIL.Image.ANTIALIAS)
      
    img.save(img_io, format="JPEG")
        
    new_pic= InMemoryUploadedFile(img_io, 
            'ImageField',
            'profile_pic',
            'JPEG',
            sys.getsizeof(img_io), None)
    return new_pic
Run Code Online (Sandbox Code Playgroud)

但这会调整图像大小,并且不会将文件保存为 jpeg,它会使用 File 类型保存文件,但何时用它替换文件名会profile_pic.jpg保存为 jpeg 类型。为什么会发生这种情况

fly*_*tle 8

由于官方文档未列出的原因field_name,中的参数需要InMemoryUploadedFile(file, field_name, name, content_type, size, charset)包含文件扩展名的完整文件名。这是一个提供一些示例用法的链接InMemoryUploadedFile(参见示例 8)

使用时获取文件扩展名应该很容易,os.path.splitext如下所示:

def image_resize(image,basewidth):
    img_io = io.BytesIO()
    img = Image.open(image)
    img_ext = list(os.path.splitext(img.filename))[-1]
    percent = (basewidth / float(img.size[0]))
    hsize = int(float(img.size[1]) * percent)
    img = img.resize((basewidth, hsize),PIL.Image.ANTIALIAS)
    img.save(img_io, format="JPEG")
        
    new_pic= InMemoryUploadedFile(img_io, 
            'ImageField',
            'profile_pic' + img_ext,
            'JPEG',
            sys.getsizeof(img_io), None)
    return new_pic

Run Code Online (Sandbox Code Playgroud)