我看了很多相同的问题,但没有解决我的问题, 我正在尝试使用按钮下载在视图中生成的文件。 问题:我在点击下载按钮
时收到一个空文件我的观点:
class dumpView(View):
template_name = 'download.html'
def get(self, request):
file = open("/home/test.pdf", "rwbt")
response = HttpResponse(file.read(), content_type="application/pdf")
response['Content-Disposition'] = 'attachement; filename=%s' % file
return render(request, 'download.html')
我的网址:
url(r'^dump/', dumpView.as_view()),
我的模板:
{% extends 'base.html' %}
{% load staticfiles %}
{% block content %}
<div class="container">
<div class="row">
<div class="jumbotron">
<div class="row">
<center>
<a href="javascript:void(0)" class="btn btn-primary btn-lg dump">Download</a>
</center>
</div>
</div>
</div>
</div>
{% endblock %}
{% block javascript %}
<script src="{% static 'js/home.js' %}"></script>
{% endblock %}
我的Django视图正在呈现响应。我确实在按钮上添加了一个on click处理程序,在UI中使用类转储对“/ dump”URL发出XHR请求,并将响应作为blob接收,并使用自定义名称和日期下载文件。
我的js:
$(".dump").on("click", function() {
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
var a, today;
if (xhttp.readyState === 4 && xhttp.status === 200) {
a = document.createElement('a');
a.href = window.URL.createObjectURL(xhttp.response);
today = new Date();
a.download = "file_" + today.toDateString().split(" ").join("_") + ".pdf";
a.style.display = 'none';
document.body.appendChild(a);
return a.click();
}
};
xhttp.open("GET", "/dump", true);
xhttp.setRequestHeader("Content-Type", "application/json");
xhttp.responseType = 'blob';
xhttp.send();
});
答案 0 :(得分:4)
在您看来,我建议您在回复中添加尺寸
content = file(filename).read()
response = HttpResponse(content, content_type='text/plain')
response['Content-Length'] = os.path.getsize(filename)
response['Content-Disposition'] = 'attachment; filename=%s' % 'my_pdf.pdf'
正如@ bob-vork所说,来自Content-Disposition
的文件名不应该是python file
对象,而是你下载的名称。
如何在urls.py中注册视图,然后用以下内容替换javascript:
<input type="button" value="Download" onclick="window.open('download_my_pdf')">
编辑:
由于您使用的是建议的HTML,我会在解决方案中添加更多详细信息。
首先,您可以删除home.js
。如你所知
<a href="javascript:void(0)" class="btn btn-primary btn-lg dump">Download</a>
变为
<input type="button" value="Download" onclick="window.open('download_my_pdf')">
您的views.py
应直接返回response
from django.http import HttpResponse
from wsgiref.util import FileWrapper
@login_required
def download_pdf(request):
filename = 'whatever_in_absolute_path__or_not.pdf'
content = FileWrapper(filename)
response = HttpResponse(content, content_type='application/pdf')
response['Content-Length'] = os.path.getsize(filename)
response['Content-Disposition'] = 'attachment; filename=%s' % 'whatever_name_will_appear_in_download.pdf'
return response
注意放置正确的content_type。请注意,我还没有测试过视图(特别是FileWrapper),我修改了一些纯文本代码。如果您将pdf视为文本文件,这也是您遇到TypeError的原因。
在urls.py
urlpatterns = (
[...]
url('download_my_pdf', download_pdf),
)
答案 1 :(得分:0)
在您的视图中,您将Content-Disposition
设置为attachment; filename=...
,但您附加了文件对象。我的猜测是浏览器可能需要一个文件名,最好是正确的扩展名。
我在Django项目中有类似的观点,我也引用了文件名,但我不确定是否有必要
编辑:此外,“附件”中有拼写错误,删除额外的“e”并查看是否有帮助