上次说到处理上传头像的方法是临时保存在本地,其实这样做并不妥,而且修改后的头像重新上传到model中也很麻烦,差了很多资料,解决了这个问题
大致思路:用户上传原图和修改数据—PIL修改后将图片保存为内存中的bytes—使用FTPstorage按规则上传到FTP—修改model中的头像路径数据
一.ContentFile\BytesIO
from PIL import Image from io import BytesIO from django.core.files.base import ContentFile def crop_image(file, left, top, right, buttom): # 打开图片 im = Image.open(file) # 剪裁图片 crop_im = im.crop((left, top, right, buttom)) # 保存图片 image_io = BytesIO() crop_im.save(fp=image_io, format='JPEG') return ContentFile(image_io.getvalue())
这里简单的写了一个修改图片的方法,因为后面要将图片上传到FTP,所以需要用之前实现的FTPstorage,经过查阅官方文档,发现storage的save操作的对象content只能是django.core.files.base里的File类以及它的子类,所以这里需要自己生成一个新的File:ContentFile,参数就是BytesIO类的的getvalue()方法,可以得到一个bytes
二.FTPstorage
def headpic_to_ftp(path, content):
storage = FTPStorage()
if storage.exists(path):
storage.delete(path)
storage.save(path, content)
else:
storage.save(path, content)
这里简单的写了一个上传的方法,path是路径和文件名,可以根据自己的需求在view中写逻辑
三.view
def user_my_info_headpic(request): # 剪裁数据获取 username = request.user headpic_name = headpic_path+'/'+str(username)+'.jpg' file = request.FILES['avatar_file'] top = int(float(request.POST['avatar_y'])) buttom = top + int(float(request.POST['avatar_height'])) left = int(float(request.POST['avatar_x'])) right = left + int(float(request.POST['avatar_width'])) # 剪裁头像 crop_file = crop_image(file, left, top, right, buttom) # 上传头像 headpic_to_ftp(headpic_name, crop_file) # 修改头像信息 userinfo = UserInfo.objects.get(username=username) userinfo.headpic=headpic_name userinfo.save() return HttpResponse("success")