zoukankan      html  css  js  c++  java
  • django 文件下载

    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=512):
            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=512):
            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
    
     
  • 相关阅读:
    布尔值
    字典及字典的索引
    列表及列表的索引
    python之基本数据类型
    python之变量
    一个python程序运行的三大步骤
    编程语言分类与介绍
    应用程序的启动流程
    爬虫之PyQuery的base了解
    Django:web认识,jinja2模块,如何安装Django
  • 原文地址:https://www.cnblogs.com/yitianyouyitian/p/9370924.html
Copyright © 2011-2022 走看看