实现model中的文件上传FTP(二)
上一篇博客记录了如何将model中的图片存入FTP,通过一个第三方的storages简单的实现了,但是后续我发现如果想在浏览器通过url直接获取图片,就不太容易了(大神轻喷,小弟自学django和python,基础知识差),于是我从头开始学习,当浏览器输入一段URL的时候,django后台究竟做了什么
一.URL处理
django在处理我们自己设计的业务请求的时候都会通过urls.py这里面的url()方法处理
def url(regex, view, kwargs=None, name=None):
if isinstance(view, (list, tuple)):
# For include(...) processing.
urlconf_module, app_name, namespace = view
return RegexURLResolver(regex, urlconf_module, kwargs, app_name=app_name, namespace=namespace)
elif callable(view):
return RegexURLPattern(regex, view, kwargs, name)
else:
raise TypeError('view must be a callable or a list/tuple in the case of include().')
简单的使用过url()或者看url的源码都知道,这里的第一个参数是获取端口号后面的url字符,用来做正则匹配的,第二个参数是处理这个请求的view方法,由于我想请求的是一个图片,只是一个静态文件,所以我联想到django在处理静态文件的url的时候,应该也会有一个特殊的方法去处理,而且这个方法是依赖setting中的debug模式是否开启(这也就是为什么关了debug,部署到服务器上的时候,django自身是提供不了静态文件的访问,因为web服务器更适合做这些工作),但是在这里卡住了。。。不知道要怎么去找这个方法,查了好久资料也没有找到,后来我想起了django的media应该和静态文件是一样的
(r'^site_media/(?P<path>.*)$', 'django.views.static.serve',{'document_root': settings.STATIC_PATH}),
这个media是一般处理用户上传的文件之类的,于是我找到了django.views.static.serve方法
def serve(request, path, document_root=None, show_indexes=False):
......
content_type, encoding = mimetypes.guess_type(fullpath)
content_type = content_type or 'application/octet-stream'
response = FileResponse(open(fullpath, 'rb'), content_type=content_type)
response["Last-Modified"] = http_date(statobj.st_mtime)
if stat.S_ISREG(statobj.st_mode):
response["Content-Length"] = statobj.st_size
if encoding:
response["Content-Encoding"] = encoding
return response
这个方法前面我省略了,大概就是判断一下URL指向的是否是一个文件,如果不是就返回报错了,真正处理的是这部分,它是返回了一个FileResponse的一个类型,看名字可以发现应该是直接返回一个文件,其实在这里我踩了好多坑,一直不知道如何给浏览器直接返回一个文件,甚至都已经把二进制文件获取到了,但是直接返回给浏览器就是乱码。。。。,不知道是不是根本原因,前端知识有限,这个FileResponse会附带一个content_type,这是一个http返回的header,将类型指定为图片,就可以展示出来了,至于这个类型,看源码也可以看到,前面用了一个mimetypes.guess_type()的方法,我大致了解了一下,这个方法只需要传URL给它就可以了,它会根据这个 URL的后缀判断,不会真的去把这个文件拿到再判断,所以不用担心它会再一次去ftp里取文件。此外,还有一些其他的header也可以设置,但是这里只用到type应该就可以了,其他的header看自己的需求

参考到这里,我们可以知道,大致思路就是自己需要重写一个url里media的view方法,用这个方法取到图片,然后返回给前端就可以了
一.get_from_ftp
这里我重写一个get_from_ftp方法来实现,其实这里我走了许多弯路。。。不知道要怎么通过storage获取到文件,而且也不知道对应的参数是什么,我这里查阅了大量的资料,然后一路碰壁,各种看源码,各种猜测,打断点。。。中间的经历过于痛苦,就不细说了(主要原因还是自己没有经验,这次也算学习到了思路),主要就是看其他地方是如何使用storage的,然后我使用的是第三方重写的ftpstorage,和其他的storage一样,是通过open方法来获取文件,参数就是路径+文件名,其实这里可以直接用media的url传过来的参数 '^media/(?P<path>.*)$'
url.py
url(r'^media/(?P<path>.*)$', get_from_ftp),
get_from_ftp
def get_from_ftp(request,path):
storage=FTPStorage()
file=storage.open(path)
content_type, encoding=mimetypes.guess_type(path)
return FileResponse(file, content_type=content_type)
其实很简单的一个逻辑,只要知道storage如何使用,很轻松就可以完成这一过程,主要还是要养成好的思考习惯,多看源码,多看文档

实现model中的文件上传FTP(二)的更多相关文章
- 实现model中的文件上传FTP(一)
由于在django的model中配置了filefield或者imagefield配置了upload_to参数只能将用户上传的文件上传到项目本地,就算重定向到项目外也只是直接读取文件系统,这样对未来的项 ...
- Java中的文件上传和下载
文件上传原理: 早期的文件上传机制: 在TCP/IP中.最早出现的文件上传机制是FTP.他是将文件由客户端发送到服务器的标准机制. jsp中的文件上传机制: 在jsp编程中不能使用FTP的方法来上传文 ...
- IIS 7 中设置文件上传大小的方法
在IIS 6.0中设置文件上传大小的方法,就是配置如下节点: <system.web> <httpRuntime maxRequestLength="1918200&quo ...
- 在WebBrowser中通过模拟键盘鼠标操控网页中的文件上传控件(转)
引言 这两天沉迷了Google SketchUp,刚刚玩够,一时兴起,研究了一下WebBrowser. 我在<WebBrowser控件使用技巧分享>一文中曾谈到过“我现在可以通过WebBr ...
- PHP中,文件上传实例
PHP中,文件上传一般是通过move_uploaded_file()来实现的. bool move_uploaded_file ( string filename, string destinati ...
- MVC中的文件上传-小结
web开发中,文件的上传是非常基本功能之一. 在asp.net中,通常做法是利用webservice 来接收文件请求,这样做的好处就是全站有了一个统一的文件上传接口,并且根据网站的实际情况,可以将we ...
- ASP.NET中的文件上传大小限制的问题
一.文件大小限制的问题 首先我们来说一下如何解决ASP.NET中的文件上传大小限制的问题,我们知道在默认情况下ASP.NET的文件上传大小限制为2M,一般情况下,我们可以采用更改WEB.Config文 ...
- struts2中的文件上传,文件下载
文件上传: Servlet中的文件上传回顾 前台页面 1.提交方式post 2.表单类型 multipart/form-data 3.input type=file 表单输入项 后台 apache提交 ...
- 转:在Struts 2中实现文件上传
(本文转自:http://www.blogjava.net/max/archive/2007/03/21/105124.html) 前一阵子有些朋友在电子邮件中问关于Struts 2实现文件上传的问题 ...
随机推荐
- 单调队列 && 单调栈
单调队列 && 单调栈 单调队列 维护某个滑动区间的min or max,可用于dp的优化 以维护min为例,采用STL双端队列实现 每次加入元素x前 先检查队首元素==滑动后要删除的 ...
- QBXT Day2
遭遇[问题描述]你是能看到第一题的 friends呢.—— hjaN座楼房,立于城中 .第i座楼,高度 hi.你需要一开始选择座楼,开始跳楼. 在第 i座楼准备跳需要 ci的花费. 每次可以跳到任何一 ...
- Proc、宿主变量、指示变量、数组变量、通信区sqlca,oraca ---(day07)
PROC 主要内容: ) proc简介 ) proc程序的开发过程 ) 宿主变量和指示变量 ) 嵌入sql语句 ) 连接数据库 ) 错误处理 ) 数据的存取更新操作 ) 动态sql --------- ...
- Linux 系统查看命令
1. linux CPU大小cat /proc/cpuinfo |grep "model name" && cat /proc/cpuinfo |grep &quo ...
- ecshop 输出数组
找到include/cls_template.php文件 找到get_val()函数,可以在大约629行加入 case 'print_r': $p = 'print_r(' . $p . ',true ...
- orcale 基本查询(1)
orcale 基本查询 查询当前用户下的所有表: select * from tab; 查询表结构: desc 表名设置行宽: set linesize 120;设置列宽: 数值类型: col 列名 ...
- 【ACM】poj_2092_Grandpa is Famous_201308021920
Grandpa is FamousTime Limit: 2000MS Memory Limit: 30000K Total Submissions: 7256 Accepted: 3670 De ...
- codevs——T1220 数字三角形
http://codevs.cn/problem/1043/ 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 查看运行结果 题目描述 Descr ...
- 编写自己的starter项目(battcn-starter-swagger)
自定义 starter 项目,方便其他地方调用,类似 spring.datasource.url 这种,本次以自己封装的 battcn-starter-swagger 为案例 创建一个Maven工程 ...
- UVA Jin Ge Jin Qu hao 12563
Jin Ge Jin Qu hao (If you smiled when you see the title, this problem is for you ^_^) For those who ...