django 文件下载
2024-08-25 01:17:11
1. 最简单下载:将文件流放入HttpResponse对象即可,适合小文件的下载,但如果这个文件非常大,这种方式会占用大量. 如:
def file_download(request):
# do something...
with open('file_name.txt') as f:
c = f.read()
return HttpResponse(c)
2. 合理的文件下载
Django的HttpResponse对象允许将迭代器作为传入参数,将上面代码中的传入参数c换成一个迭代器 ,便可以将上述下载功能优化为对大小文件均适合.更加合理的文件下载功能,应该先写一个迭代器,用于处理文件, 然后将这个迭代器作为参数传递给StreaminghttpResponse对象,如:
from django.http import StreamingHttpResponse def big_file_download(request):
# do something... def file_iterator(file_name, chunk_size=):
with open(file_name) as f:
while True:
c = f.read(chunk_size)
if c:
yield c
else:
break the_file_name = "file_name.txt"
response = StreamingHttpResponse(file_iterator(the_file_name)) return response
3.最优文件下载
上述的代码,已经完成了将服务器上的文件,通过文件流传输到浏览器,但文件流通常会以乱码形式显示到浏览器中, 而非下载到硬盘上,因此,还要在做点优化,让文件流写入硬盘。优化很简单,给StreamingHttpResponse对象 的Content-Type和Content-Disposition字段赋下面的值即可,如:
response['Content-Type'] = 'application/octet-stream'
response['Content-Disposition'] = 'attachment;filename="test.pdf"' 完整代码如下: from django.http import StreamingHttpResponse def big_file_download(request):
# do something... def file_iterator(file_name, chunk_size=):
with open(file_name) as f:
while True:
c = f.read(chunk_size)
if c:
yield c
else:
break the_file_name = "big_file.pdf"
response = StreamingHttpResponse(file_iterator(the_file_name))
response['Content-Type'] = 'application/octet-stream'
response['Content-Disposition'] = 'attachment;filename="{0}"'.format(the_file_name) return response
4.文件名包含中文下载时文件名不对,原因是: url编码解码 ,解决方法如下
from django.utils.http import urlquote response[‘Content-Disposition‘] = ‘attachment;filename="%s"‘ % (urlquote(title))
5. 遇到的问题:
下面可以下载成功:
def cmdb_export(request):
"""
下载文件,发调用写好的 下载文件的 函数总是报错,直接写过来没问题.
:param request:
:return:
"""
if request.method=="GET":
print("导出ip...........hosts")
dir_create()
remove_file("hosts")
obj = ServerConfInfo.objects.filter(deleted=False)
for i in obj:
filename = file_creat(file_name='hosts', mode="a", content=i.ip_net) response = StreamingHttpResponse(file_iterator(filename))
response['Content-Type'] = 'application/octet-stream'
response['Content-Disposition'] = 'attachment;filename="{0}"'.format(filename)
return response else:
pass
可是改成调用写好的下载函数就报错 didn't return an HttpResponse object. It returned None instead
def cmdb_export(request):
"""
下载文件,发调用写好的 下载文件的 函数总是报错,直接写过来没问题.
:param request:
:return:
"""
if request.method=="GET":
print("导出ip...........hosts")
dir_create()
remove_file("hosts")
obj = ServerConfInfo.objects.filter(deleted=False)
for i in obj:
filename = file_creat(file_name='hosts', mode="a", content=i.ip_net) dj_downloadfile(request,filename) ##这里调用写好的下载函数。
# txt = file_iterator(filename)
# response = StreamingHttpResponse(file_iterator(filename))
# response['Content-Type'] = 'application/octet-stream'
# response['Content-Disposition'] = 'attachment;filename="{0}"'.format(filename)
# return response else:
pass
dj_downloadfile()函数如下:
def dj_downloadfile(request,filename):
"""
网页下载数据,发现引用该函数会出现错误,但是把代码拷贝过去是正常的.
:param request:
:param filename:
:return:
"""
response = StreamingHttpResponse(file_iterator(filename))
response['Content-Type'] = 'application/octet-stream'
response['Content-Disposition'] = 'attachment;filename="{0}"'.format(filename)
return response
最新文章
- ID还是普通字段做外键合适?
- http 各个状态码及对应的java 编程
- Scalaz(54)- scalaz-stream: 函数式多线程编程模式-Free Streaming Programming Model
- 标准MDL方法修改Page、NonPage内存的属性
- PacketiX VPN搭建企业VPN
- Java之UncaughtExceptionHandler
- [原创]cocos2d-x + Lua接入iOS原生SDK的实现方案
- 通过ftp模拟网盘
- Win10开发必备:Visual Studio 2015正式版下载
- mysql_config not found
- sem_timedwait的用法
- ASP.NET - 分页
- Echarts笔记——使用AJAX填充数据
- Hive调优实践
- Maven maven-compiler-plugin版本
- (@WhiteTaken)设计模式学习——享元模式
- 关于String中的不变模式
- Lambda表达式Contains方法(等价于SQL语句中的like)使用注意事项
- GUI:GUI的方式创建/训练/仿真/预测神经网络—Jason niu
- Spark MLlib使用有感