Django自定义Storage实现图片上传至各大OSS(上篇)
目录
- Django默认Storage介绍
- 自定义Storage
- `__init__()`构造函数
- `open()`函数
- `save()`函数
- `delete()`函数
- `url()`函数
- `path()`函数
- 使用自定义Storage的两个方法
- 1.替换默认的Storage
- 2.为个别字段设置自定义Storage(推荐)
- 关于更多
Django默认Storage介绍
在Django的Model字段中,有诸如FileField
、ImageField
这些具有文件存储作用的字段类型。而这些默认字段的存储Django给我们做了默认的配置,我们可以通过upload_to
参数指定文件在本地的存放路径。下面是个简化后的例子。
from django.db import models
class Item(models.Model):name = models.TextField(verbose_name="产品名称")image = models.ImageField(verbose_name="产品图片", upload_to="item")
例子中,我们定义了一个Item表,内有一个name
字段表示产品名称,一个image
字段用来储存产品的图片(假设一个产品只需要一张图片),当然还有一个隐式自动生成的id
字段,这不在本文的探讨范围,忽略。
我们使用upload_to
参数指定了存放路径为item
,但要注意的是,此字段完整的存放路径是MEDIA_ROOT + upload_to
,假设项目的MEDIA_ROOT
为E:\Project\TestProject\media
,那么完整存放路径即为E:\Project\TestProject\media\item
。因此,我们还需要在settings.py
中设置MEDIA_ROOT
的路径。
settings.py
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
其中BASE_DIR
是Django在settings.py
文件头部定义好的一个变量,里面存储的是此Django项目所在本地路径,此处要区别项目路径和settings.py
所在路径,一般settings.py
文件所在路径的父级即为项目路径。
接着,我们就可以使用了,不过这篇讲的是自定义Storage,默认Storage的测试流程就跳过啦。
自定义Storage
想必看过上面的内容我们可以知道,Django的默认Storage只能实现将文件存放本地的功能。但如果我想把文件存放到远程服务器上,比如阿里云OSS、七牛云图床这些呢?这就需要我们进行自定义Storage了。
所以,自定义Storage用来解决文件远程存储读取的功能。下面讲解如何自定义一个Storage类。
首先我们新建一个MyStorage.py
文件,导入必需的基类。
from django.core.files.storage import Storage
我们自定义的Storage
正是基于Django提供的Storage
基类。这里作者打算以阿里云OSS为例定义一个Storage
,代码如下。
class OssStorage(Storage):path = ""def __init__(self, path: str = ""):self.path = pathif not path.endswith("/"):self.path = self.path + "/"def save(self, name, content, max_length=None):"""文件保存:param name: 上传时的文件名称,包含后缀名:param content: 文件内容,File对象:param max_length: 文件最大二进制长度:return: 文件路径"""# todo 处理保存文件逻辑,返回相对文件路径return pathdef delete(self, name):"""删除文件:param name: 相对路径文件名,此处并非上传时的文件名,而是在save()函数中返回的文件名:return: """# todo 处理删除文件逻辑,无返回def url(self, name):"""返回文件的url地址:param name: 相对路径文件名,此处并非上传时的文件名,而是在save()函数中返回的文件名:return:"""# todo 处理返回文件url逻辑,返回文件的url地址return urldef path(self, name):"""返回文件的相对路径地址:param name: 相对路径文件名,此处并非上传时的文件名,而是在save()函数中返回的文件名:return: 相对路径地址"""# todo 处理返回文件相对路径地址,一般返回name自身或者与url()一致,具体看自身业务逻辑return namedef open(self, name, mode='rb'):"""打开文件操作,一般pass即可:param name: 相对路径文件名,此处并非上传时的文件名,而是在save()函数中返回的文件名:param mode: 打开方式,默认'rb':return:"""pass
我们定义了一个OssStorage
类并继承自Storage
类,并重载了sava()
、delete()
、url()
、path()
、open()
五个函数以及一个__init__()
构造函数,并设置了一个path
参数用于接收文件存放的根路径。其中open
和save
为必需方法。下面,我们逐一对这些方法进行讲解。
注:此篇仅讲解自定义Storage的结构,没有具体实现代码。具体代码将在下篇与封装各平台的对象存储SDK一起讲解。
__init__()
构造函数
def __init__(self, path: str = ""):self.path = pathif not path.endswith("/"):self.path = self.path + "/"
构造函数定义了一个path
参数,并用一个同名的类成员变量path
接收,并对path
有无/
进行判断及处理,方便后期的链接拼接。
path
这个参数用来设置文件上传的根路径,可以类比默认Storage的upload_to
参数。设置path
参数可以方便我们对上传的文件进行分组存放,例如用户头像的path
可以设置为/user/protrait
,产品图片的path
可以设置为/product/image
,如此一来,后期便可以很方便的在远程服务器中对文件进行管理。
open()
函数
def open(self, name, mode='rb'):"""打开文件操作,一般pass即可:param name: 相对路径文件名,此处并非上传时的文件名,而是在save()函数中返回的文件名:param mode: 打开方式,默认'rb':return:"""pass
open()
函数是Storage要求必须重载的函数,但这函数一般情况下并不需要写任何代码,因此只要重载后pass
即可。
save()
函数
def save(self, name, content, max_length=None):"""文件保存:param name: 上传时的文件名称,包含后缀名:param content: 文件内容,File对象:param max_length: 文件最大二进制长度:return: 文件路径"""# todo 处理保存文件逻辑,返回相对文件路径return path
save()
函数也是Storage要求必须重载的函数,这个函数负责处理用户选择文件后进行上传时图片的保存操作(应用场景例子:Django后台管理页面的文件上传)。它接受三个参数name
、content
和max_length
。
name
参数为文件上传时的原始文件名。原始文件名并不受服务端控制,因此总是千奇百怪。通常情况下并不会使用此值,而是根据业务环境重新生成新的文件名进行存储。content
参数为一个File
对象,里面包含着文件的二进制数据,可用content.read()
获取。
file_data = content.read()
max_length
参数,当它不存在吧,没啥用。
save()
函数要求返回一个str
类型的值,用来表示相对路径地址
。所谓相对路径地址
是指文件在OSS中存放的路径地址,在一些OSS的SDK中称之为key
。例如,用户上传的文件名为a.jpg
,save()
函数生成了一个新的文件名为new.jpg
,Storage类构造函数的path
值为/project/test/
,那么相对路径地址
为/project/test/new.jpg
。
注:相对路径地址
用于唯一确定一个文件,在OSS中用于查找某个文件
delete()
函数
def delete(self, name):"""删除文件:param name: 相对路径文件名,此处并非上传时的文件名,而是在save()函数中返回的文件名:return: """# todo 处理删除文件逻辑,无返回
delete()
函数仅有一个name
参数,这个参数即为相对路径地址
。通过delete()
函数调用OSS SDK中的删除文件接口,传递name
参数,即可实现文件的删除。此函数无返回值。
url()
函数
def url(self, name):"""返回文件的url地址:param name: 相对路径文件名,此处并非上传时的文件名,而是在save()函数中返回的文件名:return:"""# todo 处理返回文件url逻辑,返回文件的url地址return url
url()
函数用于返回某一文件的url
访问地址,此地址要求可以直接访问。此函数有一个name
参数,用于传递文件的相对路径地址
,通过在函数中进行一定的业务逻辑处理,获得该文件url
访问地址,并使用return返回。
path()
函数
def path(self, name):"""返回文件的相对路径地址:param name: 相对路径文件名,此处并非上传时的文件名,而是在save()函数中返回的文件名:return: 相对路径地址"""# todo 处理返回文件路径地址,一般返回name自身或者与url()一致,具体看自身业务逻辑return name
path()
函数用于返回某一个文件的路径地址,此地址可为相对路径地址
,也可为url
访问地址,具体根据项目的业务逻辑决定。
使用自定义Storage的两个方法
写好自定义Storage后,当然是使用它了。有如下两个使用方法
1.替换默认的Storage
如果想为所有的文件字段采用自定义的Storage,可以采取替换默认Storage的方法,具体方法为在settings.py
中设置DEFAULT_FILE_STORAGE
settings.py
DEFAULT_FILE_STORAGE = 'utils.fdfs.storage.FDFSStorage'
之后便可以按照原来的方法定义文件字段了。
使用此方法需去除upload_to
参数
2.为个别字段设置自定义Storage(推荐)
有时我们并不想替换默认的Storage,而是仅仅将一些比较重要的图片存储到远程服务器中,这时就可以修改Model类的代码进行实现。这里我们就以之前的Item Model为例,修改代码如下:
from MyStorage import OssStorage
from django.db import models
class Item(models.Model):name = models.TextField(verbose_name="产品名称")image = models.ImageField(verbose_name="产品图片", storage=OssStorage("project/images"), max_length=2048)
可见,我们去除了up_load
参数,设置storage
参数为我们自定义的OssStorage
类,给构造函数path
参数传值project/images
,这样,我们自定义Storage就完成了!
使用此方法后MEDIA_ROOT
配置将无效
关于更多
本篇只讲解了自定义Storage的结构及应用,每个重载函数的具体实现代码并未编写,且还未讲解如何将自定义Storage与各大OSS SDK对接。这些都将在《Django自定义Storage实现图片上传至各大OSS(下篇)》中介绍。
Django自定义Storage实现图片上传至各大OSS(上篇)相关推荐
- android 自定义图片上传,android自定义ImageView仿图片上传示例
看下效果图 主要看下自定义view 代码 public class ProcessImageView extends ImageView{ private Context context; priva ...
- android 自定义图片上传,android自定义ImageView仿图片上传(示例代码)
Activity代码 1 public classMainActivity extends AppCompatActivity {2 ProcessImageView processImage ...
- .NET自定义多文件(图片)上传的实现方式
目的:通过输入要显示传图片的数量,自动创建相对应数量的上传控件,进行一次性上传操作. 默认有一个上传控件,当输入2时并点击添加按钮后,下面又显示了2个控件,效果如下: 点击全部上传按钮后的效果: CS ...
- 一步步带你实现一个简单的express服务器,能让vue通过axios请求将图片上传到阿里云OSS
文章目录 前言 一.申请阿里云OSS 二.Vue前端读取图片 三.将图片base64转成二进制文件 四.搭建express服务器 五.通过axios给服务器发送请求 六.发送图片并上传阿里云 我们首先 ...
- 使用SpringBoot将图片上传至阿里云OSS
一. 对象存储OSS 1. 什么是OSS? 官方的解释是这样的:阿里云对象存储OSS(Object Storage Service)是一款海量.安全.低成本.高可靠的云存储服务,提供99.999999 ...
- Java 常用工具类(9) : 图片上传至阿里云OSS
阿里云OSS工具类 加强版 : https://blog.csdn.net/Lxinccode/article/details/79698259 import java.io.ByteArrayInp ...
- 【Typora图床设置】Typora图片上传和阿里云OSS对象存储
问题描述 因为Typora是纯文本编辑器,所以无法导入图片,但是可以显示图片.换句话说,Typora文档中保存的图片实际上是图片的存储地址,Typora会根据这个地址来显示图片.我们在使用Typora ...
- 图片上传到阿里云OSS
目录 Why? What? How? Why? 有一个需求是上传图片到阿里云上的OOS中,可能对于一些 没有用阿里云部署项目的不是很了解,现在小编就带大家入门一下: What? 对象存储服务(Obj ...
- HTTP Content-Type (MIME) el-upload文件、图片上传 | 文件改名 | 大文件 | 文件下载
MIME 为数据格式标签:最初 MIME 是用于电子邮件系统的,后来 HTTP 也采用了这一方案. 在HTTP协议消息头中,使用Content-Type来表示请求和响应中的媒体类型信息. Conten ...
最新文章
- 数据治理展示血缘关系的工具_Nebula Graph 在微众银行数据治理业务的实践
- Git@OSC 增加 SVN 支持
- python读取excelsheet-一文看懂用Python读取Excel数据
- job 做 ha 问题?
- JZOJ 5221. 【GDOI2018模拟7.10】A
- C++求复数的角度_人教A版高中数学必修二7.1 复数的概念优质课公开课课件、教案...
- python2与python3,Python2和Python3的10大区别
- 递归算法思路以及题目总结(未完待续...)
- FPGA积沙成塔(目录篇)
- BT.2020 新一代超高清UHD视频制作与显示系统标准
- C语言移动营业厅程序设计,【程序设计论文】C语言教学的移动应用程序设计(共2486字)...
- oracle sql monitor
- 一款小游戏集合自动脚本
- 【HTTP图片服务器】【项目记录2】:安装、配置MySQL环境
- 《SpringSecurity in Action》四:Session共享下的Session并发控制问题
- SLAM基础问题总结(1)
- 服务器做RAID,各个RAID特点
- win10网络邻居看到linux,win10网络邻居找不到其他电脑怎么办
- koa框架数据导出为excel格式
- java一竖,java 添加一个竖滚动条
热门文章
- 历代诗词咏宁夏注释1----常星景: 六盘
- English--元音
- 阿里云视频点播视频播放出现network timeout问题处理
- oracle查询员工表领导级别,emp表中怎么统计每个员工的领导的年薪,并按年薪由高到低排列...
- 《数据结构与算法分析》之插入排序
- 2021-01-30关于IE浏览器被篡改主页无法修改的解决办法
- 为什么要学习 Linux?
- 终端/SSH/Telnet ConnectBot v1.7.1中文版
- 苹果申请屏幕防指纹专利 互联网信用体系跨越一大步
- 3.29 判断电脑无线网卡是否支持5GHz频段