美文网首页
storage.py:

storage.py:

作者: seventhboy | 来源:发表于2016-11-23 17:08 被阅读25次

    -- coding: UTF-8 --

    from os import environ

    debug = not environ.get("APP_NAME", "") #判断sae环境
    from django.utils.translation import ugettext as _
    from django.core.files.storage import FileSystemStorage
    from django.core.exceptions import ImproperlyConfigured, SuspiciousOperation
    from django.conf import settings
    import time,os,uuid,random,unicodedata,StringIO
    from django.core.files.base import ContentFile
    if not debug:
    import sae
    import tempfile
    import sae.storage
    from PIL import Image #这里是关键,sae加载Image的方式
    else:
    import Image

    class SaeAndNotSaeStorage(FileSystemStorage):
    """
    这是一个支持sae和本地django的FileStorage基类
    修改存储文件的路径和基本url
    """
    def init(self, location=settings.MEDIA_ROOT, base_url=settings.MEDIA_URL):
    super(SaeAndNotSaeStorage, self).init(location, base_url)

    def get_valid_name(self, name):
    """
    这个方法用于验证文件名,我这里的处理方法是去掉中文,我没有找到支持中文名的方法,欢迎补充
    """

    name = unicodedata.normalize('NFKD', name).encode('ascii', 'ignore')

    处理中文文件名sae不支持

    if not debug:
    try:
    if 1:

    去掉中文

    name = unicodedata.normalize('NFKD', name).encode('ascii', 'ignore')
    else:
    for k in name:
    if self.is_chinese(k):
    name = "wszw%s"%random.randint(0,100)
    except Exception,e:
    name = "%s.jpg"%type(name)

    end

    return super(SaeAndNotSaeStorage, self).get_valid_name(name)

    @property
    def maxsize(self):
    return 1010241024#文件2M--sae限制只能传2M,单个文件,据说是10M,其实只有2M

    @property
    def filetypes(self):
    return []

    def makename(self,name):

    取一个不重复的名字,sae会把重名覆盖

    oname = os.path.basename(name)
    path = os.path.dirname(name)

    首先判断是否需要重命名---也就是说不想改名字的就加这个前缀

    if oname.find("mine")==0:
    oname = oname.replace("mine","")
    name = os.path.join(path, oname)
    return name

    end---首先判断是否需要重命名

    try:
    fname, hk = oname.split(".")
    except Exception,e:
    fname, hk = oname, ''
    if hk:
    rname = "%s_%s.%s"%(random.randint(0,10000), fname,hk)
    else:
    rname = "%s_%s"%(random.randint(0,10000), fname)
    name = os.path.join(path, rname)

    end

    return name

    def _save(self, name, content):
    """
    可以判断上传哪些文件
    """
    hz = name.split(".")[-1]

    类型判断

    if self.filetypes!='*':
    if hz.lower() not in self.filetypes:
    raise SuspiciousOperation(u"不支持的文件类型,支持%s"%self.filetypes)

    end

    name = self.makename(name)

    大小判断

    if content.size > self.maxsize:
    raise SuspiciousOperation(u"文件大小超过限制")

    end

    保存

    if not debug:
    s = sae.storage.Client()
    if hasattr(content, '_get_file'):#admin入口
    ob = sae.storage.Object(content._get_file().read())
    else:#view入口(ContentFile)
    ob = sae.storage.Object(content.read())
    url =s.put('image', name, ob) #注意这里的media,是sae-storage上的domain名
    return name
    else:
    return super(SaeAndNotSaeStorage, self)._save(name, content)

    end--保存

    def delete(self,name):
    """
    sae的存储空间很宝贵,所有我们在删除图片数据库记录的时候也需要删除图片
    """
    if not debug:
    s = sae.storage.Client()
    try:
    s.delete('image', name)
    except Exception,e:
    pass
    else:
    super(SaeAndNotSaeStorage, self).delete(name)

    class ImageStorage(SaeAndNotSaeStorage):
    """
    实现一个ImageField的Storage
    """
    @property
    def maxsize(self):
    return 210241024#文件2M

    @property
    def filetypes(self):
    return ['jpg','jpeg','png','gif']

    class FileStorage(SaeAndNotSaeStorage):
    @property
    def maxsize(self):
    return 1010241024#文件5M

    @property
    def filetypes(self):
    return "*"

    def makename(self, name):

    return name

    class ThumbStorage(ImageStorage):
    """
    缩略图-------这个非常关键,处理后的图片在sae上怎么保存,关键就在StringIO
    """
    def _save(self, name, content):

    处理

    image = Image.open(content)
    image = image.convert('RGB')
    image.thumbnail((50, 50), Image.ANTIALIAS)

    output = StringIO.StringIO()
    image.save(output,'JPEG')
    co = ContentFile(output.getvalue())
    output.close()

    end

    return super(ThumbStorage, self)._save(name, co)

    调用的model.py:
    from storage import ImageStorage,FileStorage,ThumbStorageiconUrl = models.ImageField(upload_to=upload_path_handler, storage=ImageStorage(),verbose_name="图片地址")

    相关文章

      网友评论

          本文标题:storage.py:

          本文链接:https://www.haomeiwen.com/subject/ahyvpttx.html