zoukankan      html  css  js  c++  java
  • django 上传图片、使用PIL制作缩略图并保存到sea的storage

    上传图片解析:

    SAE的设置指引如下:

    处理用户上传文件

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

    # 修改上传时文件在内存中可以存放的最大size为10m
    FILE_UPLOAD_MAX_MEMORY_SIZE = 10485760
    
    # sae的本地文件系统是只读的,修改django的file storage backend为Storage
    DEFAULT_FILE_STORAGE = 'sae.ext.django.storage.backend.Storage'
    # 使用media这个bucket
    STORAGE_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.py
    from django.db.models.fields.files import ImageField,ImageFieldFile
    from PIL import Image
    def _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不支持直接的目录结构,但可以通过文件名来模拟目录结构
  • 相关阅读:
    使用 Promise.all 同时发起多个请求
    vite 开发 Cesium 程序最佳配置实践
    【linux学习】使用grep命令获取过滤的数据作为下个命令的入参
    记一次k8s depolyment失败处理
    powerdesigner导出excel数据字典
    vue 时间格式
    ASP.NET MVC4 跨域配置
    Win10系统中切换虚拟桌面的快捷键如何设置
    不顾一切最简NHinbernate配置并读写数据库
    Windows time_wait过多解决办法
  • 原文地址:https://www.cnblogs.com/qwj-sysu/p/4473502.html
Copyright © 2011-2022 走看看