django从服务端下载文件到本地的方法有哪些
这篇文章主要介绍django从服务端下载文件到本地的方法有哪些,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!
在实际的项目中很多时候需要用到下载功能,如导excel、pdf或者文件下载,当然你可以使用web服务自己搭建可以用于下载的资源服务器,如nginx,这里我们主要介绍django中的文件下载。
这里我们将下载的文件存放在项目media目录下,当然在实际中并不会这样做。
方式一:使用HttpResponse
importosfromdjango.httpimportHttpResponse,Http404defmedia_file_download(request,file_path):withopen(file_path,'rb')asf:try:response=HttpResponse(f)response['content_type']="application/octet-stream"response['Content-Disposition']='attachment;filename='+os.path.basename(file_path)returnresponseexceptException:raiseHttp404
HttpResponse有个很大的弊端,其工作原理是先读取文件,载入内存,然后再输出。如果下载文件很大,该方法会占用很多内存。对于下载大文件,Django更推荐StreamingHttpResponse和FileResponse方法,这两个方法将下载文件分批(Chunks)写入用户本地磁盘,先不将它们载入服务器内存。
方式二:使用StreamingHttpResponse
importosfromdjango.httpimportHttpResponse,Http404,StreamingHttpResponsedefstream_http_download(request,file_path):try:response=StreamingHttpResponse(open(file_path,'rb'))response['content_type']="application/octet-stream"response['Content-Disposition']='attachment;filename='+os.path.basename(file_path)returnresponseexceptException:raiseHttp404
方式三:使用FileResponse
importosfromdjango.httpimportHttpResponse,Http404,FileResponsedeffile_response_download1(request,file_path):try:response=FileResponse(open(file_path,'rb'))response['content_type']="application/octet-stream"response['Content-Disposition']='attachment;filename='+os.path.basename(file_path)returnresponseexceptException:raiseHttp404
文件名中文乱码问题
其中用英文的文件名,浏览器显示正常,但是用了中文后,就是默认的文件名,如下载.xls,或者如果我用了utf-8编码,是乱码。解决方法如下:
response['Content-Disposition']="attachment;filename*=utf-8''{}".format(escape_uri_path(name))
文件私有化的两种方法
如果你想实现只有登录过的用户才能查看和下载某些文件,大概有两种方法,这里仅提供思路。
上传文件放在media文件夹,文件名使用很长的随机字符串命名(uuid), 让用户无法根据文件名猜出这是什么文件。视图和模板里验证用户是否已登录,登录或通过权限验证后才显示具体的url。- 简单易实现,安全性不高,但对于一般项目已足够。
上传文件放在非media文件夹,用户即使知道了具体文件地址也无法访问,因为Django只会给media文件夹里每个文件创建独立url资源。视图和模板里验证用户是否已登录,登录或通过权限验证后通过自己编写的下载方法下载文件。- 安全性高,但实现相对复杂。
个人下载文档view视图代码
fromdjango.viewsimportViewfromdjango.confimportsettingsfromdjango.httpimportFileResponse,Http404fromdjango.utils.encodingimportescape_uri_pathfrom.modelsimportDocimportrequestsimportlogginglogger=logging.getLogger('django')classDownload(View):"""前端传来下载doc的id,后端传给它下载地址"""defget(self,request,doc_id):doc=Doc.objects.only('file_url').filter(is_delete=False,id=doc_id).first()ifdoc:doc_url=doc.file_urldoc_url=settings.ITEM_DOMAIN_PORT+doc_urltry:res=FileResponse(requests.get(doc_url,stream=True))exceptExceptionase:logger.info('文件获取异常:{}'.format(e))raiseHttp404('文件获取异常')file_end=doc_url.split('.')[-1]ifnotfile_end:raiseHttp404('文档路径出错')else:file_end=file_end.lower()iffile_end=="pdf":res["Content-type"]="application/pdf"eliffile_end=="zip":res["Content-type"]="application/zip"eliffile_end=="doc":res["Content-type"]="application/msword"eliffile_end=="xls":res["Content-type"]="application/vnd.ms-excel"eliffile_end=="docx":res["Content-type"]="application/vnd.openxmlformats-officedocument.wordprocessingml.document"eliffile_end=="ppt":res["Content-type"]="application/vnd.ms-powerpoint"eliffile_end=="pptx":res["Content-type"]="application/vnd.openxmlformats-officedocument.presentationml.presentation"else:raiseHttp404("文档格式不正确!")doc_filename=escape_uri_path(doc_url.split('/')[-1])#http1.1中的规范#设置为inline,会直接打开#attachment浏览器会开始下载res["Content-Disposition"]="attachment;filename*=UTF-8''{}".format(doc_filename)returnreselse:raiseHttp404("文档不存在!")
以上是django从服务端下载文件到本地的方法有哪些的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注亿速云行业资讯频道!
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。