Django 如何下载现有文件?

Posted

技术标签:

【中文标题】Django 如何下载现有文件?【英文标题】:Django How to download existing file? 【发布时间】:2017-11-21 07:10:03 【问题描述】:

在我的 Django 视图中,我创建了一个 pdf 文件,我想下载它。 该文件存在(路径:/app/data/4.pdf),我启动此命令:

def download_line(request):
    if not request.is_ajax() and not request.method == 'GET':
        raise Http404

    try:
        fs =FileSystemStorage('/app/data')
        with fs.open('4.pdf') as pdf:
            response =HttpResponse(pdf,content_type='application/pdf')
            response['Content-Disposition']='attachment; filename="4.pdf"'


    except Exception as e:
        logger.warning("Download Line | Erreur : " + e.message)


    return response

但是下载没有开始并且没有错误。你有解决办法吗? 谢谢。

【问题讨论】:

也许你需要在pdf(文件)对象上调用read()方法。即HttpResponse(pdf.read(), cont… 不行,我应该在javascript端下载? 您似乎想使用 Ajax 提供文件,这是不可能的:***.com/questions/4545311/… 好的,我无法使用 Ajax 从服务器下载文件,如何在 javascript 端执行此操作? 只需使用<a href=...> 即可下载。 ***.com/a/31040851/1977847 【参考方案1】:

当文件已经存在时,我使用FileResponse 来提供文件下载。 FileResponse 自 Django 1.7.4 以来一直存在。

from django.core.files.storage import FileSystemStorage
from django.http import FileResponse

def download_line(request):
    fs = FileSystemStorage('/absolute/folder/name')
    FileResponse(fs.open('filename.pdf', 'rb'), content_type='application/force-download')
    response['Content-Disposition'] = 'attachment; filename="filename.pdf"'
    return response

【讨论】:

【参考方案2】:

您可以像这样通过链接和静态文件在您的应用中下载现有文件

<a href="% static 'questions/import_files/import_questions.xlsx' %" download>Excel Format File </a>

【讨论】:

【参考方案3】:

试试这个,我用这行来下载文件

from django.http import HttpResponse
from wsgiref.util import FileWrapper

import os

def download(request, file_path):
    """
    e.g.: file_path = '/tmp/file.pdf'
    """
    try:
        wrapper = FileWrapper(open(file_path, 'rb'))
        response = HttpResponse(wrapper, content_type='application/force-download')
        response['Content-Disposition'] = 'inline; filename=' + os.path.basename(file_path)
        return response
    except Exception as e:
        return None

【讨论】:

它不起作用,错误“视图 paquet.views.download 没有返回 HttpResponse 对象。它返回了 None”,pb 似乎是包装器时 file_path 不正确时会发生此错误 @smiss 根据示例,该函数需要C:\tmp\file.pdf (Windows) 或/tmp/file.pdf (Linux) 中的文件【参考方案4】:
def sample_download_client_excel(request):
    """
    e.g.: file_path = '/tmp/file.pdf'
    """
    try:
        obj = SampleFile.objects.all().first()
        file_path = obj.file_name.url.strip('/') 
        wrapper = FileWrapper(open(file_path, 'rb'))
        response = HttpResponse(
            wrapper, 
            content_type='application/force-download'
        )
        response['Content-Disposition'] = 'inline; filename=' + os.path.basename(file_path)
        return response
    except Exception as e:
        return None

【讨论】:

以上是关于Django 如何下载现有文件?的主要内容,如果未能解决你的问题,请参考以下文章

将现有图像文件与 Django 模型相关联

我们如何在 django 中更改现有用户表中的字段名称

Django 上传:丢弃上传的重复文件,使用现有文件(基于 md5 的检查)

Django 如何实现文件下载

Django现有模型增加字段

Django:从服务器上的现有文件手动创建模型中的图像字段