I use the following snippet to generate a CSV for my queryset. It also includes related fields, that you can choose to ignore or use something else to serialize the data. ( Such as the default serializers that come with Django )
import csv
def dump_to_csv(model, qs):
"""
Takes in a Django queryset and spits out a CSV file.
"""
model = qs.model
writer = ''
headers = []
# Get standard fields
for field in model._meta.get_fields():
headers.append(field) if 'extra' not in field.name else None
writer += ','.join([field.name for field in headers])
writer += '\n'
for obj in qs:
row = []
for field in headers:
# Append all general fields
if field.get_internal_type() not in ['ForeignKey', 'ManyToManyField', 'OneToOneField']:
val = getattr(obj, field.name)
if callable(val):
val = val()
if type(val) == str:
val = val.encode("utf-8")
row.append(str(val))
# Append all fk fields
elif field.get_internal_type() in ['ForeignKey', 'OneToOneField']:
from django.core import serializers
import json
value = field.value_from_object(obj)
if value not in [None, ""]:
qs = field.remote_field.model.objects.filter(pk=value)
json_data = serializers.serialize("json", qs, fields=(field.name for field
in qs.first()._meta.get_fields() if
'extra' not in field.name))
json_data = [o['fields'] for o in json.loads(json_data)]
json_data = json.dumps(json_data)
json_data = json_data.replace(",", ";")
json_data = json_data.replace("\"", "'")
row.append(json_data)
else:
row.append("[]")
# Append all m2m fields
elif field.get_internal_type() in ['ManyToManyField']:
from django.core import serializers
import json
qs = getattr(obj, field.name).all()
json_data = serializers.serialize("json", qs)
json_data = [o['fields'] for o in json.loads(json_data)]
json_data = json.dumps(json_data)
json_data = json_data.replace(",", ";")
json_data = json_data.replace("\"", "'")
row.append(json_data)
writer += ','.join(row)
writer += '\n'
return writer
The reason I have this is because my use case requires me to have a JSON dump of each related object as well.
You can then return this in the response so:
file = dump_to_csv(qs.model, qs)
response = HttpResponse(file, content_type='text/csv')
response['Content-Disposition'] = u'attachment; filename="{0}"'.format('export.csv')
return response