Skip to content

Instantly share code, notes, and snippets.

@bennylope
Last active December 22, 2015 14:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bennylope/6486182 to your computer and use it in GitHub Desktop.
Save bennylope/6486182 to your computer and use it in GitHub Desktop.
A simple way of avoiding duplication in CSV exports. This example takes advantage of Python's `attrgetter` function to get chained attributes using strings like "attr.subattr.subattr".
import csv
from operator import attrgetter
def generic_csv(csvfile, objects, fields):
writer = csv.writer(csvfile, quoting=csv.QUOTE_ALL)
row_headers = fields.keys()
writer.writerow(row_headers)
for obj in objects:
row = [attrgetter(fields[header])(obj) for header in row_headers]
for count, column in enumerate(row):
if callable(column):
row[count] = column()
if type(column) is unicode:
row[count] = column.encode('utf8')
writer.writerow(row)
return csvfile
import csv
from operator import attrgetter
from collections import OrderedDict
from django.contrib.auth.models import User
from myapp.models import UserProfile
def generic_csv(csvfile, objects, fields):
"""
Accepts a queryset and writes the fields specified in the fields dictionary
to the passed csvfile.
Chained attributes are handled by Python's builtin `attrgetter` function
"""
writer = csv.writer(csvfile, quoting=csv.QUOTE_ALL)
row_headers = fields.keys()
writer.writerow(row_headers)
for obj in objects:
row = [attrgetter(fields[header])(obj) for header in row_headers]
for count, column in enumerate(row):
if callable(column):
row[count] = column()
if type(column) is unicode:
row[count] = column.encode('utf8')
writer.writerow(row)
return csvfile
def csv_view(request):
"""
View function that returns a CSV formatted list of site users.
Presumes that there is a user profile model defined and
associated with the User model via a OneToOneRelationship.
It's important to use select_related here otherwise each profile
will have to be queried for the city and avatar each time.
"""
response = HttpResponse(mimetype='text/csv')
response['Content-Disposition'] = "attachment; filename=site-users.csv"
fields = OrderedDict([
("First name", "first_name"),
("Last name", "last_name"),
("Email", "email"),
("City", "profile.city"),
("Avatar", "profile.avatar"),
])
return generic_csv(response, User.objects.select_related('profile').all(), fields)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment