目录

  • Django默认Storage介绍
  • 自定义Storage
    • `__init__()`构造函数
    • `open()`函数
    • `save()`函数
    • `delete()`函数
    • `url()`函数
    • `path()`函数
  • 使用自定义Storage的两个方法
    • 1.替换默认的Storage
    • 2.为个别字段设置自定义Storage(推荐)
  • 关于更多

Django默认Storage介绍

在Django的Model字段中,有诸如FileFieldImageField这些具有文件存储作用的字段类型。而这些默认字段的存储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_ROOTE:\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参数用于接收文件存放的根路径。其中opensave为必需方法。下面,我们逐一对这些方法进行讲解。
注:此篇仅讲解自定义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后台管理页面的文件上传)。它接受三个参数namecontentmax_length

  • name参数为文件上传时的原始文件名。原始文件名并不受服务端控制,因此总是千奇百怪。通常情况下并不会使用此值,而是根据业务环境重新生成新的文件名进行存储。
  • content参数为一个File对象,里面包含着文件的二进制数据,可用content.read()获取。
file_data = content.read()
  • max_length参数,当它不存在吧,没啥用。
    save()函数要求返回一个str类型的值,用来表示相对路径地址。所谓相对路径地址是指文件在OSS中存放的路径地址,在一些OSS的SDK中称之为key。例如,用户上传的文件名为a.jpgsave()函数生成了一个新的文件名为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(上篇)相关推荐

  1. android 自定义图片上传,android自定义ImageView仿图片上传示例

    看下效果图 主要看下自定义view 代码 public class ProcessImageView extends ImageView{ private Context context; priva ...

  2. android 自定义图片上传,android自定义ImageView仿图片上传(示例代码)

    Activity代码 1 public classMainActivity extends AppCompatActivity {2     ProcessImageView processImage ...

  3. .NET自定义多文件(图片)上传的实现方式

    目的:通过输入要显示传图片的数量,自动创建相对应数量的上传控件,进行一次性上传操作. 默认有一个上传控件,当输入2时并点击添加按钮后,下面又显示了2个控件,效果如下: 点击全部上传按钮后的效果: CS ...

  4. 一步步带你实现一个简单的express服务器,能让vue通过axios请求将图片上传到阿里云OSS

    文章目录 前言 一.申请阿里云OSS 二.Vue前端读取图片 三.将图片base64转成二进制文件 四.搭建express服务器 五.通过axios给服务器发送请求 六.发送图片并上传阿里云 我们首先 ...

  5. 使用SpringBoot将图片上传至阿里云OSS

    一. 对象存储OSS 1. 什么是OSS? 官方的解释是这样的:阿里云对象存储OSS(Object Storage Service)是一款海量.安全.低成本.高可靠的云存储服务,提供99.999999 ...

  6. Java 常用工具类(9) : 图片上传至阿里云OSS

    阿里云OSS工具类 加强版 : https://blog.csdn.net/Lxinccode/article/details/79698259 import java.io.ByteArrayInp ...

  7. 【Typora图床设置】Typora图片上传和阿里云OSS对象存储

    问题描述 因为Typora是纯文本编辑器,所以无法导入图片,但是可以显示图片.换句话说,Typora文档中保存的图片实际上是图片的存储地址,Typora会根据这个地址来显示图片.我们在使用Typora ...

  8. 图片上传到阿里云OSS

    目录 Why? What? How? Why? 有一个需求是上传图片到阿里云上的OOS中,可能对于一些 没有用阿里云部署项目的不是很了解,现在小编就带大家入门一下: What?  对象存储服务(Obj ...

  9. HTTP Content-Type (MIME) el-upload文件、图片上传 | 文件改名 | 大文件 | 文件下载

    MIME 为数据格式标签:最初 MIME 是用于电子邮件系统的,后来 HTTP 也采用了这一方案. 在HTTP协议消息头中,使用Content-Type来表示请求和响应中的媒体类型信息. Conten ...

最新文章

  1. 数据治理展示血缘关系的工具_Nebula Graph 在微众银行数据治理业务的实践
  2. Git@OSC 增加 SVN 支持
  3. python读取excelsheet-一文看懂用Python读取Excel数据
  4. job 做 ha 问题?
  5. JZOJ 5221. 【GDOI2018模拟7.10】A
  6. C++求复数的角度_人教A版高中数学必修二7.1 复数的概念优质课公开课课件、教案...
  7. python2与python3,Python2和Python3的10大区别
  8. 递归算法思路以及题目总结(未完待续...)
  9. FPGA积沙成塔(目录篇)
  10. BT.2020 新一代超高清UHD视频制作与显示系统标准
  11. C语言移动营业厅程序设计,【程序设计论文】C语言教学的移动应用程序设计(共2486字)...
  12. oracle sql monitor
  13. 一款小游戏集合自动脚本
  14. 【HTTP图片服务器】【项目记录2】:安装、配置MySQL环境
  15. 《SpringSecurity in Action》四:Session共享下的Session并发控制问题
  16. SLAM基础问题总结(1)
  17. 服务器做RAID,各个RAID特点
  18. win10网络邻居看到linux,win10网络邻居找不到其他电脑怎么办
  19. koa框架数据导出为excel格式
  20. java一竖,java 添加一个竖滚动条

热门文章

  1. 历代诗词咏宁夏注释1----常星景: 六盘
  2. English--元音
  3. 阿里云视频点播视频播放出现network timeout问题处理
  4. oracle查询员工表领导级别,emp表中怎么统计每个员工的领导的年薪,并按年薪由高到低排列...
  5. 《数据结构与算法分析》之插入排序
  6. 2021-01-30关于IE浏览器被篡改主页无法修改的解决办法
  7. 为什么要学习 Linux?
  8. 终端/SSH/Telnet ConnectBot v1.7.1中文版
  9. 苹果申请屏幕防指纹专利 互联网信用体系跨越一大步
  10. 3.29 判断电脑无线网卡是否支持5GHz频段