Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
"Export to CSV" action for django admin
import unicodecsv
from django.http import HttpResponse
def export_as_csv_action(description="Export selected objects as CSV file",
fields=None, exclude=None, header=True):
"""
This function returns an export csv action
'fields' and 'exclude' work like in django ModelForm
'header' is whether or not to output the column names as the first row
"""
def export_as_csv(modeladmin, request, queryset):
opts = modeladmin.model._meta
if not fields:
field_names = [field.name for field in opts.fields]
else:
field_names = fields
response = HttpResponse(mimetype='text/csv')
response['Content-Disposition'] = 'attachment; filename=%s.csv' % unicode(opts).replace('.', '_')
writer = unicodecsv.writer(response, encoding='utf-8')
if header:
writer.writerow(field_names)
for obj in queryset:
row = [getattr(obj, field)() if callable(getattr(obj, field)) else getattr(obj, field) for field in field_names]
writer.writerow(row)
return response
export_as_csv.short_description = description
return export_as_csv
from django.contrib import admin
from repsf.map.models import Location
from django.http import HttpResponse, HttpResponseForbidden
from actions import export_as_csv_action
class SpamAdmin(admin.ModelAdmin):
list_display = ['wink','nudge']
actions = [export_as_csv_action("CSV Export", fields=['wink','nudge'])]
admin.site.register(Location, LocationAdmin)
@chan24092005

This comment has been minimized.

Copy link

@chan24092005 chan24092005 commented Nov 21, 2017

in newer version of python and httpResponse, it should be

        response = HttpResponse(content_type='text/csv')
        response['Content-Disposition'] = 'attachment; filename=%s.csv' % str(opts).replace('.', '_')
@JamieRobertson

This comment has been minimized.

Copy link

@JamieRobertson JamieRobertson commented Jul 31, 2018

This is great. Does the exclude argument do anything though?

@JamieRobertson

This comment has been minimized.

Copy link

@JamieRobertson JamieRobertson commented Jul 31, 2018

Could the exclude argument be used like this?

if not fields:
    field_names = [field.name for field in meta.fields]
else:
    field_names = fields

if exclude:
    exclude_names = exclude.split() if isinstance(exclude, str) else exclude  # exclude could be a string
    field_names = [x for x in field_names if x not in list(exclude_names)]

Here exclude could be passed in as a list, a tuple, or a string.

@JamieRobertson

This comment has been minimized.

Copy link

@JamieRobertson JamieRobertson commented Jul 31, 2018

*Corrected an error - must assign exclude to a new variable 'exclude_names', or local variable referenced before assignment error will be thrown

@dfranc3373

This comment has been minimized.

Copy link

@dfranc3373 dfranc3373 commented Aug 31, 2018

Amazing job on this one

@hlodver

This comment has been minimized.

Copy link

@hlodver hlodver commented Sep 25, 2018

Sometimes it can be useful to follow foreign keys If that is what you need you can use:

def rgetattr(obj, attr, *args):
    def _getattr(obj, attr):
        return getattr(obj, attr, *args)
    return functools.reduce(_getattr, [obj] + attr.split('__'))

Just import functools and be careful not to go too deep Django docs for the QuerySet API.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment