首页 > 学院 > 开发设计 > 正文

django上传图片、使用PIL制作缩略图并保存到sea的storage

2019-11-14 17:14:08
字体:
来源:转载
供稿:网友

上传图片解析:

SAE的设置指引如下:

处理用户上传文件

在setttings.py中添加以下配置。

# 修改上传时文件在内存中可以存放的最大size为10mFILE_UPLOAD_MAX_MEMORY_SIZE = 10485760# sae的本地文件系统是只读的,修改django的file storage backend为StorageDEFAULT_FILE_STORAGE = 'sae.ext.django.storage.backend.Storage'# 使用media这个bucketSTORAGE_BUCKET_NAME = 'media'# ref: https://docs.djangoPRoject.com/en/dev/topics/files/

 

分两种情况:
  • 图片是数据库中的一个字段,比如说:
class Picture(models.Model):    """docstring for Picture"""    user = models.ForeignKey(Customer)    image = ThumbnailImageField(upload_to='goods_photo')

 然后你只需要在视图函数里面这么写就ok了,这时候SAE是可以自动帮你帮图片上传到storage中的domain为media下的goods_photo文件夹下了(记得在SAE上激活storage并建立一个名为你在settings.py设定的STORAGE_BUCKET_NAME,还有在这个domain下面建立一个名为你设定的upload_to的值的文件夹)

def upload_photo(request):    f = request.FILES['upload_file']    name=copy.copy(f.name)    p = Picture()    p.image = f    user_id = request.POST['user_id']    user = Customer.objects.get(pk=user_id)    p.user = user    p.save()
  •  直接上传图片到storage

参考sea的storage的api文档,链接

下面开始做正事了
我的目标是上传一个图片并生成一个缩略图,图片是数据库的一个字段,缩略图通过该数据库的一个自定义属性thumb_url 访问这个缩略图
自定义一个ThumbnailImageField,参考代码如下
# ThumbnailImageField.pyfrom django.db.models.fields.files import ImageField,ImageFieldFilefrom PIL import Imagedef _add_thumb(s):    parts = s.split(".")    parts.insert(-1,"thumb")    if parts[-1].lower() not in ['jpeg','jpg']:        parts[-1]='jpg'    return ".".join(parts)class ThumbnailImageFieldFile(ImageFieldFile):    def _get_thumb_url(self):        return _add_thumb(self.url)    thumb_url = property(_get_thumb_url)    def save(self,name,content,save=True):        super(ThumbnailImageFieldFile, self).save(name,content,save)    def delete(self,save=True):        super(ThumbnailImageFieldFile, self).delete(save)        class ThumbnailImageField(ImageField):    """docstring for ThumbnailImageField"""    attr_class = ThumbnailImageFieldFile    def __init__(self,*args,**kwargs):        super(ThumbnailImageField, self).__init__(*args,**kwargs)
视图函数参考如下
def upload_photo(request):    f = request.FILES['upload_file']    name=copy.copy(f.name)    p = Picture()    p.image = f    user_id = request.POST['user_id']    user = Customer.objects.get(pk=user_id)    p.user = user    p.save()    c = sae.storage.Connection()    bucket = c.get_bucket('media')    obj = bucket.get_object_contents("goods_photo/"+name)    image = Image.open(StringIO(obj))    image.thumbnail((90,90),Image.ANTIALIAS)    imgOut = StringIO()    image.save(imgOut, 'jpeg')    img_data = imgOut.getvalue()    bucket.put_object('goods_photo/'+_add_thumb(name), img_data)    imgOut.close()

 视图函数详细讲解:

p.save()会消耗掉request.FILES['upload_file'],所以建议的做法是先保存这个文件到storage中,然后再从storage中把这个图片取出来进行处理
name=copy.copy(f.name),之所以使用浅拷贝也是因为 p.save()会消耗掉request.FILES['upload_file'],直接name=f.name的话拿到的name就不知道是什么了,当然你也可以使用deepcopy,但是没必要,因为name就是一个字符串
bucket.get_object_contents("goods_photo/"+name),sea的storage不支持直接的目录结构,但可以通过文件名来模拟目录结构

 


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表