开发者社区> apachecn_飞龙> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

django 1.8 官方文档翻译: 3-5-1 使用Django输出CSV

简介: 使用Django输出CSV 这篇文档阐述了如何通过使用Django视图动态输出CSV (Comma Separated Values)。
+关注继续查看

使用Django输出CSV

这篇文档阐述了如何通过使用Django视图动态输出CSV (Comma Separated Values)。 你可以使用Python CSV 库或者Django的模板系统来达到目的。

使用Python CSV库

Python自带了CSV库,csv。在Django中使用它的关键是,csv模块的CSV创建功能作用于类似于文件的对象,并且Django的HttpResponse对象就是类似于文件的对象。

这里是个例子:

import csv
from django.http import HttpResponse

def some_view(request):
    # Create the HttpResponse object with the appropriate CSV header.
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename="somefilename.csv"'

    writer = csv.writer(response)
    writer.writerow(['First row', 'Foo', 'Bar', 'Baz'])
    writer.writerow(['Second row', 'A', 'B', 'C', '"Testing"', "Here's a quote"])

    return response

代码和注释是不用多说的,但是一些事情需要提醒一下:

  • 响应对象获得了一个特殊的MIME类型,text/csv。这会告诉浏览器,文档是个CSV文件而不是HTML文件。如果你把它去掉,浏览器可能会把输出解释为HTML,会在浏览器窗口中显示一篇丑陋的、可怕的官样文章。
  • 响应对象获取了附加的Content-Disposition协议头,它含有CSV文件的名称。文件名可以是任意的;你想把它叫做什么都可以。浏览器会在”另存为“对话框中使用它,或者其它。
  • 钩住CSV生成API非常简单:只需要把response作为第一个参数传递给csv.writercsv.writer 函数接受一个类似于文件的对象,而HttpResponse 对象正好合适。
  • 对于你CSV文件的每一行,调用writer.writerow,向它传递一个可迭代的对象比如列表或者元组。
  • CSV模板会为你处理引用,所以你不用担心没有转义字符串中的引号或者逗号。只需要向writerow()传递你的原始字符串,它就会执行正确的操作。

在Python 2中处理Unicode

Python2的csv模块不支持Unicode输入。由于Django在内部使用Unicode,这意味着从一些来源比如HttpRequest读出来的字符串可能导致潜在的问题。有一些选项用于处理它:

  • 手动将所有Unicode对象编码为兼容的编码。
  • 使用csv模块示例章节中提供的UnicodeWriter类。
  • 使用python-unicodecsv 模块,它作为csv模块随时可用的替代方案,能够优雅地处理Unicode。

更多信息请见csv模块的Python文档。

流式传输大尺寸CSV文件

当处理生成大尺寸响应的视图时,你可能想要使用Django的StreamingHttpResponse类。例如,通过流式传输需要长时间来生成的文件,可以避免负载均衡器在服务器生成响应的时候断掉连接。

在这个例子中,我们利用Python的生成器来有效处理大尺寸CSV文件的拼接和传输:

import csv

from django.utils.six.moves import range
from django.http import StreamingHttpResponse

class Echo(object):
    """An object that implements just the write method of the file-like
    interface.
    """
    def write(self, value):
        """Write the value by returning it, instead of storing in a buffer."""
        return value

def some_streaming_csv_view(request):
    """A view that streams a large CSV file."""
    # Generate a sequence of rows. The range is based on the maximum number of
    # rows that can be handled by a single sheet in most spreadsheet
    # applications.
    rows = (["Row {}".format(idx), str(idx)] for idx in range(65536))
    pseudo_buffer = Echo()
    writer = csv.writer(pseudo_buffer)
    response = StreamingHttpResponse((writer.writerow(row) for row in rows),
                                     content_type="text/csv")
    response['Content-Disposition'] = 'attachment; filename="somefilename.csv"'
    return response

使用模板系统

或者,你可以使用Django模板系统来生成CSV。比起便捷的Python csv模板来说,这样比较低级,但是为了完整性,这个解决方案还是在这里展示一下。

它的想法是,传递一个项目的列表给你的模板,并且让模板在for循环中输出逗号。

这里是一个例子,它像上面一样生成相同的CSV文件:

from django.http import HttpResponse
from django.template import loader, Context

def some_view(request):
    # Create the HttpResponse object with the appropriate CSV header.
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename="somefilename.csv"'

    # The data is hard-coded here, but you could load it from a database or
    # some other source.
    csv_data = (
        ('First row', 'Foo', 'Bar', 'Baz'),
        ('Second row', 'A', 'B', 'C', '"Testing"', "Here's a quote"),
    )

    t = loader.get_template('my_template_name.txt')
    c = Context({
        'data': csv_data,
    })
    response.write(t.render(c))
    return response

这个例子和上一个例子之间唯一的不同就是,这个例子使用模板来加载,而不是CSV模块。代码的结果 – 比如content_type='text/csv' – 都是相同的。

然后,创建模板my_template_name.txt,带有以下模板代码:

{% for row in data %}"{{ row.0|addslashes }}", "{{ row.1|addslashes }}", "{{ row.2|addslashes }}", "{{ row.3|addslashes }}", "{{ row.4|addslashes }}"
{% endfor %}

这个模板十分基础。它仅仅遍历了提供的数据,并且对于每一行都展示了一行CSV。它使用了addslashes模板过滤器来确保没有任何引用上的问题。

其它基于文本的格式

要注意对于 CSV来说,这里并没有什么特别之处 – 只是特定了输出格式。你可以使用这些技巧中的任何一个,来输出任何你想要的,基于文本的格式。你也可以使用相似的技巧来生成任意的二进制数据。例子请参见在Django中输出PDF

译者:Django 文档协作翻译小组,原文:Generating CSV

本文以 CC BY-NC-SA 3.0 协议发布,转载请保留作者署名和文章出处。

Django 文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。交流群:467338606。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
【Django学习笔记 - 11】:模板的继承、模型类和数据库
【Django学习笔记 - 11】:模板的继承、模型类和数据库
20 0
Django 中url补充以及模板继承
Django中的URL补充 默认值 在url写路由关系的时候可以传递默认参数,如下: url(r'^index/', views.index,{"name":"root"}), 这样在视图函数中,就可以获取这个默认参数name: def index(request,name): ...
762 0
08.Django自定义模板,自定义标签和自定义过滤器
一:自定义模板 模板继承我们可以简单的理解为类的继承,其实他们有很大的相似之处,定义一个基类模板,我们便可以在子页面中进行引用,django中模板中的块用block进行标示,他属于django自定义的tag 例如:我们定义了一个基类的模板base.
1055 0
django的模板页面里,如何获取一个集合的数据?
以前以为是用[下标],原来在模板,也作了变换,得用. 才能搞定。 如下例中的 object_list.0.server_type 'nginx'    {% ifequal object_list.0.server_type 'nginx' %} 发布程序    回滚 {% endifequal %} 下午休息。
1009 0
01.Django学习之安装,建立项目,传参,MySQL数据库,静态文件配置和模板的使用
1:安装 pip install Django==1.8.6 2:建立项目  进入某个目录执行 django-admin.py startproject myweb(此为项目目录)  建立子目录:         先进入 myweb目录,然后执行 manage.
1139 0
DJANGO模板的BLOCK自定义技巧
除了INCLUDE, EXTENDS基本的继承模板之外,如果想在本模板上,直接生成让同类页面继承的模板, 则可以需要自定义的地方实现自定义BLOCK, 先在本页面实现自己的BLOCK,然后,在继承的页面实现另外的BLOCK。
1097 0
django基础入门(3)django中模板
上一节中的输入,即视图中的return HttpResponse()部分。函数中的内容为…… 意思就是,前端文件,要每次都要手写,打印,这非常麻烦。通常,它会包括很多内容,还有js文件,css文件等。
847 0
django 1.8 官方文档翻译: 2-3-2 关联对象参考
Django 文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。 交流群:467338606 网站:http://python.usyiyi.cn/django/index.html 关联对象参考 class RelatedManager “关联管理器”是在一对多或者多对多的关联上下文中使用的管理器。
746 0
+关注
apachecn_飞龙
Github:@wizardforcel 简书:@ApacheCN_飞龙 微博:@龙雀 CSDN:@wizardforcel ApacheCN 官网:apachecn.org 机器学习交流群:629470233
文章
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载