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

How to create InMemoryUploadedFile objects proper in django

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

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

但是这会调整图像大小并且它不会将文件另存为 jpeg 而是将文件保存为文件类型 但是当用 profile_pic.jpg 替换文件名时,它会保存为 jpeg 类型。 为什么会这样

InMemoryUploadedFile(file, field_name, name, content_type, size, charset) 中的 field_name 参数需要包含文件扩展名的完整文件名,原因是 official documentation does not list. Here is a link 给出了 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