storage.py:

-- 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="图片地址")

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,755评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,369评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,799评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,910评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,096评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,159评论 3 411
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,917评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,360评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,673评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,814评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,509评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,156评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,123评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,641评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,728评论 2 351

推荐阅读更多精彩内容