我想使用类似模板的语法生成CSV文件(或任何合理的导出格式)的数据,以访问我的django对象的字段。例如,输出字段的规范可以是:
employee.id
employee.manager.first_name
employee.user.last_login
employee.contact.phone_number
使用与我在Django或Jinja2模板中使用的语法相同的语法指定字段。
我也喜欢能像django / jinja模板一样使用过滤器:
employee.user.last_login|date:"c"
鉴于此规范和对象列表,我想从我的对象生成数据行。然后,我可以从这些数据中生成CSV,XML等。
我开始写一些这样做的东西,但很快变得复杂,我想我可能会使用一些现有的Django / Jinja2模板引擎。
是否允许我通过Django / Jinja2语法访问我的对象?
答案 0 :(得分:1)
首先,使用除csv
模块之外的任何技术生成CSV数据不会赢得许多朋友;这是工作的正确工具。
使用该模块生成输出的方便的方法是writer.writerows()
,它采用嵌套列表(或者更确切地说,是序列的迭代器)。生成器是一种很好的表达方式:
def csv_spec(queryset):
for employee in queryset:
yield (
employee.id,
employee.manager.first_name,
employee.user.last_login,
employee.contact.phone_number)
w = csv.writer(outfile)
w.writerows(csv_spec(something))
编辑:所以你说你想要像模板一样的东西,原因与我们使用模板的原因相同,但它产生的是CSV而不是文本。你可以让jinja解析并处理它所拥有的各种表达式 没有完整模板的占位符。
假设我们有一些数据:
>>> from collections import namedtuple
>>> from datetime import datetime
>>> Employee = namedtuple('Employee', 'id manager user contact')
>>> Person = namedtuple('Person', 'first_name last_name')
>>> Account = namedtuple('Account', 'username password last_login')
>>> Contact = namedtuple('Contact', 'phone_number email')
>>> data = [
... Employee(0, Person('Alice', 'Brown'),
... Account('abrown', 'secret', datetime(2013, 3, 3)),
... Contact('5551234', 'abrown@example.com')),
... Employee(1, Person('Bob', 'Jones'),
... Account('bjones', 'safe', datetime(2013, 3, 3)),
... Contact('5555678', 'bjones@example.com')),
... Employee(2, Person('Carol', 'Smith'),
... Account('csmith', 'hidden', datetime(2013, 3, 3)),
... Contact('5559012', 'csmith@example.com'))]
和模板(您可以轻松地从文件中读取此内容)
>>> import StringIO
>>> template = StringIO.StringIO('''employee.id
... employee.manager.first_name
... employee.user.last_login
... employee.contact.phone_number''')
要使用表达式编译器,您需要一个环境;没有选择 指定:
>>> import jinja2
>>> env = jinja2.Environment()
>>> template_filter = map(env.compile_expression, template)
正如我所提到的,使用csv模块:
>>> import csv
>>> import sys
>>> writer = csv.writer(sys.stdout)
最后,通过编译后的表达式,我们可以遍历数据,一个''行' 一个时间,并为每一行,应用每个表达式
>>> writer.writerows([[field(employee=row) for field in template_filter]
... for row in data])
0,Alice,2013-03-03 00:00:00,5551234
1,Bob,2013-03-03 00:00:00,5555678
2,Carol,2013-03-03 00:00:00,5559012
答案 1 :(得分:0)
Django Docs是一个很好的资源 - http://docs.python.org/2/library/csv.html
您需要知道的是python中用于访问对象属性的点符号。