[Answer]-Django/Jinja2 : Generate (data for) CSV via template syntax

1👍

First off, generating CSV data with any technique other than the csv module will not win you many friends; it’s the right tool for the job.

the most convenient way to generate output with that module is with writer.writerows(), which takes a nested list (or rather, iterator of sequences). Generators are a good way of expressing exactly that:

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))

Edit: So you are saying you want something like a template for the same reason we use templates, but which produces CSV instead of text. You can ask jinja to parse and process the sorts of expressions it has in
placeholders without a full template.

Assuming we have some data:

>>> 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'))]

and a template (you could read this from a file as easily)

>>> import StringIO
>>> template = StringIO.StringIO('''employee.id
... employee.manager.first_name
... employee.user.last_login
... employee.contact.phone_number''')

To use the expression compiler, you need an Environment; no options need be
specified:

>>> import jinja2
>>> env = jinja2.Environment()
>>> template_filter = map(env.compile_expression, template)

As I mentioned, use the csv module:

>>> import csv
>>> import sys
>>> writer = csv.writer(sys.stdout)

finally, with the compiled expressions, we can run over the data, one ‘row’ at
a time, and for each row, apply each expression

>>> 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

0👍

The Django Docs are an excellent resource – http://docs.python.org/2/library/csv.html

All you need to know is the dot notation used in python to access object properties.

Leave a comment