django 1.8 官方文档翻译: 3-5-1 使用Django输出CSV
使用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 HttpResponsedef 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.writer
。csv.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 csvfrom django.utils.six.moves import range
from django.http import StreamingHttpResponseclass Echo(object):"""An object that implements just the write method of the file-likeinterface."""def write(self, value):"""Write the value by returning it, instead of storing in a buffer."""return valuedef 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, Contextdef 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 1.8 官方文档翻译: 3-5-1 使用Django输出CSV相关推荐
- django 1.8 官方文档翻译: 2-5-7 自定义查找
自定义查找 New in Django 1.7. Django为过滤提供了大量的内建的查找(例如,exact和icontains).这篇文档阐述了如何编写自定义查找,以及如何修改现存查找的功能.关于查 ...
- django 1.8 官方文档翻译: 2-5-6 多数据库
多数据库 这篇主题描述Django 对多个数据库的支持.大部分Django 文档假设你只和一个数据库打交道.如果你想与多个数据库打交道,你将需要一些额外的步骤. 定义你的数据库 在Django中使用多 ...
- django 1.8 官方文档翻译:13-1-3 密码管理
Django中的密码管理 密码管理在非必要情况下一般不会重新发明,Django致力于提供一套安全.灵活的工具集来管理用户密码.本文档描述Django存储密码和hash存储方法配置的方式,以及使用has ...
- django 1.8 官方文档翻译:13-3 日志
日志 日志快速入门 Django 使用Python 内建的logging 模块打印日志.该模块的用法在Python 本身的文档中有详细的讨论.如果你从来没有使用过Python 的logging 框架( ...
- django 1.8 官方文档翻译: 8-3 点击劫持保护
点击劫持保护 点击劫持中间件和装饰器提供了简捷易用的,对点击劫持的保护.这种攻击在恶意站点诱导用户点击另一个站点的被覆盖元素时出现,另一个站点已经加载到了隐藏的frame或iframe中. 点击劫持的 ...
- django 1.8 官方文档翻译: 2-5-10 数据库函数
数据库函数 New in Django 1.8. 下面记述的类为用户提供了一些方法,来在Django中使用底层数据库提供的函数用于注解.聚合或者过滤器等操作.函数也是表达式,所以可以像聚合函数一样混合 ...
- django 1.8 官方文档翻译: 3-3-5 编写自定义存储系统
编写自定义存储系统 如果你需要提供自定义文件存储 – 一个普遍的例子是在某个远程系统上储存文件 – 你可以通过定义一个自定义的储存类来实现.你需要遵循以下步骤: 1. 你的自定义储存类必须是djang ...
- django 1.8 官方文档翻译: 3-5-2 使用Django输出PDF
使用Django输出PDF 这篇文档阐述了如何通过使用Django视图动态输出PDF.这可以通过一个出色的.开源的Python PDF库ReportLab来实现. 动态生成PDF文件的优点是,你可以为 ...
- django 1.8 官方文档翻译: 2-3-1 模型实例参考
模型实例参考 该文档详细描述模型 的API.它建立在模型 和执行查询 的资料之上, 所以在阅读这篇文档之前,你可能会想要先阅读并理解那两篇文档. 我们将用执行查询中所展现的 博客应用模型 来贯穿这篇参 ...
最新文章
- Redis 6.0 新特性-多线程连环13问!
- 解决tensorflow报错ValueError: Variable conv1/weights already exists, disallowed.
- 关于silverlight5 打印功能收集
- little kernel中如何决定app目录下应该包含哪个app
- spring 各个jar包的功能
- SAP License:ERP财务软件简介
- tensorflow获取可用GPU设备
- Mysql的跨表更新
- 关于opencv4.5.3读取视频失败问题
- 几款引擎比较:BigWorld,Unreal,CryEngine等
- gps高斯utm_UTM投影分带计算与高斯投影分带计算
- ESP8266AT指令集学习笔记
- 本质与现象:本质与现象
- Matlab - Solidworks 机器人建模(6)——使用rigidBodyTree构建机器人模型
- matlab中lms m,LMS算法仿真(Matlab)
- 【通讯录教程】Excel表格批量手机号码导入安卓和苹果手机的通讯录,下面教你方法
- runC 严重漏洞,使用容器的快打补丁;辩论界人机大战,人类获胜
- 【HTML/CSS】创建日期和时间表单控件
- 同时拥有多个子域名和主域名?推荐申请GlobalSign SANs SSL证书
- UTC时间转换为当前时区时间
热门文章
- Vivado过程文件解释
- FPGA状态机三段式
- 做系统ghost步骤图解_掌握这几个步骤电脑小白也会做系统
- 判断给定的两个数是否是亲和数_动画演示LeetCode算法题:004-寻找两个有序数组的中位数...
- 【Proteus】如何在Proteus中将网络标号批量标号
- [MFC] CDialog::DoModal()函数用法
- linux 复用寄存器,I/O多路复用一些概念
- Syslog4j介绍
- Elasticsearch Java API四种实现方式
- Java中HashMap和TreeMap的区别