Django实现静态文件缓存到云服务的操作方法
作者:纵横千里,捭阖四方 发布时间:2023-05-26 07:52:54
一般与页面有关的系统都会有大量的静态文件,包括js、css以及图标图片等,这些文件一般是项目的相对路径,在加载的时候会从本地读取再转发出去。由于这类文件一般比较大,导致接口响应变长,但是这些文件一般很少改动,所以非常适合通过Nginx或者云服务来缓存。一般云服务与cdn无缝集成,能够更快下发到客户端。我们后台系统很多使用的是基于python的Django框架,该怎么来实现静态文件缓存呢?
这个过程简单的让人惊讶,但是开始一直搞不清楚关系,前前后后耽误了不少时间。
1.collectstatic命令
首先 Django有一个collectstatic的命令,该脚本的功能是将本地的静态文件以及需要的依赖,例如Django和python自己需要的静态文件等打包到一个统一的目录下。这有点类似于maven发布前的打包功能。
这个脚本一般在上线的时候会执行。例如我们的启动脚本里这么写的:
sh collectstatic.sh
然后在djang的配置文件里加这么一行:
static-map = /static=./static_files
我们将本地的静态文件打包发送到云服务就是用collectstatic来实现的。
2.如何发布到云服务
方法非常简单,代码也非常少,但是貌似很多地方都没说清楚为什么,害的我搞了好久,白了很多垃圾代码。
首先你要新建一个继承了Storage的类,例如这样子:
@deconstructible
class CosStorage(Storage):
上面的注解也必须要有的。
然后在很多材料里会将,要在这里类里实现多个方法,有的是以_开头,有的就是普通的类,我理解_开头的主要是collectstatic执行的方法,而不带的是程序执行的时候调用的。前者类似java中的各类service,程序启动的时候就会执行。而后者类似controller下的接口,只有外部调用的时候才会执行。
以_开头的方法最重要的是下面这三个:
def __init__(self):
logging.info('init cos file list...')
self.get_cos_file_list()
# 看看这里是否需要
def _open(self, name, mode='r'):
return File(open(self.path(name), mode))
def _save(self, name, content):
cms.util.upload_os_file(FileBizType.TRUMAN_CMS_STATIC_FILES, content, name, name)
time.sleep(0.02)
__init__自然是为了初始化而设置的。根据需要写对应的代码,例如调用云服务需要的签名等等
_open()这个我当时忘了测试一下有没有用了,按道理这里是打开文件的,反正我是上么这么写的。
_save(self, name, content)是最关键的代码。这个接口是理解Storage的两大钥匙。这个方法的功能是处理当前已经打开的文件,文件标题就是name,content就是将文件内容转换成的字节流,你直接用就行。这个该怎么理解呢?
name的含义:假如你的静态路径很深,文件很多,类型也很杂。那么Storage首先就帮你处理路径的问题了,name就是相对路径+文件名。所以你传的时候使用name就将相对目录一起传过去了。
content的含义:content就是文件的内容,不管是js、css、还是图标图片,在网络传的时候都会先转换成字节流是不是。这里的content就是当前文件的字节流。所以就使用upload_os_file(content) 就将文件内容发出去了,不需要自己再读文件 ,转换成字节流等操作。不过这里的upload_os_file是我自己的业务代码,你可以根据需要做对应的实现。
另外一个重要的问题是_save一次只处理一个文件,所以你写这个方法里的代码的时候只要考了一个文件就行了,不用多此一举写批量等逻辑。
这里还有一点就是如果不加限制,_save的执行速度会非常快 ,一下就将所有文件全部读到,并且一个文件一个请求全部发出去,这可能导致服务端来不及处理而被拒绝等情况。方法也很简单,_save里加个等待就行了
time.sleep(0.02)
上面的代码在服务启动过程中执行到collectstatic时会自动扫描,自动加载,自动执行,但是你要在自己的配置文件中添加如下信息,否则会找不到。
STATICFILES_STORAGE = 'cos.cos_storage.CosStorage'
3.访问时是如何重定向到cos的
将文件存到云服务之后,页面执行的时候怎么访问呢?
这就涉及到Storage的其他几个方法了,主要是:
def listdir(self, path):
pass
def delete(self, name):
pass
def size(self, name):
pass
def url(self, name):
url = cms.util.get_file_os_download_url(name)
return url
def exists(self, name):
pass
上面看名字我们就能大致知道功能,最重要的是url()方法,这个是理解Storage的第二把钥匙。
这里的name就是文件在云服务中的相对路径,你需要将拼接一下你的域名等就是文件的地址了。然后返回就行了。
如果静态文件都是公开的,这里的url貌似不写也行,能够自动实现将域名和文件相对路径拼接程完整的访问url。
但是在我们的系统中,静态文件是不允许直接访问,需要带签名的。 所以我们这里需要在url里通过自定义的get_file_os_download_url()方法去访问我们另外一个服务。
但是这里有一个坑,就是python的基础包中也会用相对路径访问自己的静态文件,也就是这么写"/title.png"等,这种情况无法被url拦截到。因为我们业务的代码里是统一加前缀/static/的。
该怎么拦截,至今没有解决,如果你知道,请和我说,谢谢!
来源:https://blog.csdn.net/xueyushenzhou/article/details/119753575


猜你喜欢
- 本文实例讲述了Python实现拷贝多个文件到同一目录的方法。分享给大家供大家参考,具体如下:有一个文件,里面存有多个文件名,一个文件名一行。
- 在mysql的手册中已经对max_user_connections有一点说明,它是用来限制用户资源的,怎么限制用户资源呢?这里做了个小测试。
- 推荐两文:1、支付宝购买流程 2、支付宝卖家流程 支付宝接口提供最新的ASP、ASP.NET、PHP、JSP等目前网络上最流行的源码包文件,
- 见下表:序号保留字序号保留字序号保留字1ADD80ESCAPE159OR2ABSOLUTE81EXCEPT160ORDER3ACTION82
- 设置密码保护SqlServer数据库备份文件! 备份SqlServer数据库 Backup Database [数据库] To disk=&
- 前言网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或
- 每个浏览器都有自己的默认样式,这是一段预定义的CSS,用以简单地呈现网页。在Firefox中的地址栏中输入resource://gre/re
- pycharm出现no module named xlwt问题首先声明,我是初学者,今天按照书上步骤,创建Excel文件,当我的xlwt安装
- sql server中变量要先申明后赋值:局部变量用一个@标识,全局变量用两个@(常用的全局变量一般都是已经定义好的);申明局部变量语法:d
- 本文实例为大家分享了基于Express框架使用POST传递Form数据的具体代码,供大家参考,具体内容如下客户端使用Form发送数据在客户端
- 第一个保存在新建一个文本中<% Dim Username,PassWord,strLogFile,f,ff,Str
- 首先说一下我遇到的坑,生产上遇到的问题,我调度Python脚本执行并监控这个进程,python脚本运行时间远远大于python脚本中自己统计
- 如果你有一字段dm记录了一个url,为了更好的优化模糊查询速度或统计速度,在数据表原有的结构上增加3个字段,分别为 `sdm`
- AXObject可用来解决IE需要激活 ActiveX 控件和生成控件调用代码 AXObjec
- 代码如下:<% set rs=server.createobject("adodb.recordset&
- 本文实例讲述了javascript设置页面背景色及背景图片的方法。分享给大家供大家参考,具体如下:<!DOCTYPE HTML PUB
- 我听说在ASP里,可以不用DSN来连接EXCEL,请问如何实现?确实ASP提供了替代DSN的其他方法,甚至可以在运行时建立连接看看下面的范例
- Python中的数据类型共有六个,分别是:字符串,数字,布尔类型,列表,元祖,字典,集合其中分为可变的类型和不可变的:可变类型:列表,字典,
- 功能:扫描当前目录下所有CSV文件并对其中文件进行统计,输出统计值到CSV文件pip install pandasimport pandas
- 前言相信看到这个题目,可能大家都觉得是一个老生常谈的月经topic了。一直以来其实把握一个“值传递”基本上就能理解各种情况了,不过最近遇到了