实现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实现文件上传的问题 ...
随机推荐
- 备份xx
https://www.tuicool.com/articles/V3EBzev https://www.tuicool.com/topics/11080087?st=0&lang=1& ...
- luogu P1856 [USACO5.5]矩形周长Picture 扫描线 + 线段树
Code: #include<bits/stdc++.h> #define maxn 200007 #define inf 100005 using namespace std; void ...
- 【转载】VMware完全卸载
出现安装时出现vmwareworkstationxxx.msi failed问题是官方解决方案...真心详细. http://kb.vmware.com/selfservice/microsites/ ...
- 7.5 pragma 指令
第1个pragma禁用了我们感兴趣的特别警告,第2个恢复了它.禁用尽可能小的一段代码的警告是一个良好的做法,以便你不会错过任何真正应该修复的错误.如果你想在单独一行上禁用或恢复多个警告,那么只需用逗号 ...
- Vue学习之路第二十篇:Vue生命周期函数-组件创建期间的4个钩子函数
1.每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听.编译模板.将实例挂载到 DOM 并在数据变化时更新 DOM 等.同时在这个过程中也会运行一些叫做生命周期钩子的函数 ...
- POJ 1979 Red and Black (BFS)
链接 : Here! 思路 : 简单的搜索, 直接广搜就ok了. /****************************************************************** ...
- android网络类型之2G-3G切换
在android手机‘设置’-‘移动网络类型’里可以看到有关网络类型的选项,一般默认为3G优先. 如果有需要在程序中切换网络类型的朋友,不妨试试下面的方法.这里提供了几种思路,虽然可能对待 手机的方式 ...
- netty心跳机制和断线重连(四)
心跳是为了保证客户端和服务端的通信可用.因为各种原因客户端和服务端不能及时响应和接收信息.比如网络断开,停电 或者是客户端/服务端 高负载. 所以每隔一段时间 客户端发送心跳包到客户端 服务端做出心 ...
- POJ 2486
因为苹果可能在不同的子树中,所以,很容易想到设状态dp_back[i][j]为以i点为树根走j步并回到i点的最大苹果数与dp_to[i][j]不回到i点的两个状态. 于是,转移方程就很明显了.只是注意 ...
- JVM基础(二) 实现自己的ClassLoader
为何要花时间实现自己的ClassLoader 尽管人生的乐趣非常大一部分来自于将时间花在有意思可是无意义的事情上,可是这件事绝对是有意思并且有意义的,有下面几个情景是值得我们花费时间实现自己的clas ...