Login

Generic CSV export admin action factory with relationship spanning fields and labels

Author:
blackrobot
Posted:
December 21, 2012
Language:
Python
Version:
1.4
Tags:
admin generic export csv admin-actions export-csv
Score:
2 (after 2 ratings)

Based on #2712

"This snippet creates a simple generic export to csv action that you can specify the fields you want exported and the labels used in the header row for each field. It expands on #2020 by using list comprehensions instead of sets so that you also control the order of the fields as well."

The additions here allow you to span foreign keys in the list of field names, and you can also reference callables.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import csv
from django.http import HttpResponse
 
 
def prep_field(obj, field):
    """ Returns the field as a unicode string. If the field is a callable, it
    attempts to call it first, without arguments.
    """
    if '__' in field:
        bits = field.split('__')
        field = bits.pop()
 
        for bit in bits:
            obj = getattr(obj, bit, None)
 
            if obj is None:
                return ""
 
    attr = getattr(obj, field)
    output = attr() if callable(attr) else attr
    return unicode(output).encode('utf-8') if output else ""
 
 
def export_csv_action(description="Export as CSV", fields=None, exclude=None, header=True):
    """ This function returns an export csv action. """
    def export_as_csv(modeladmin, request, queryset):
        """ Generic csv export admin action.
        Based on http://djangosnippets.org/snippets/2712/
        """
        opts = modeladmin.model._meta
        field_names = [field.name for field in opts.fields]
        labels = []
 
        if exclude:
            field_names = [f for f in field_names if f not in exclude]
 
        elif fields:
            field_names = [field for field, _ in fields]
            labels = [label for _, label in fields]
 
        response = HttpResponse(mimetype='text/csv')
        response['Content-Disposition'] = 'attachment; filename=%s.csv' % (
                unicode(opts).replace('.', '_')
            )
 
        writer = csv.writer(response)
 
        if header:
            writer.writerow(labels if labels else field_names)
 
        for obj in queryset:
            writer.writerow([prep_field(obj, field) for field in field_names])
        return response
    export_as_csv.short_description = description
    return export_as_csv


## Example Usage

from django.contrib import admin

 
class ExampleModelAdmin(admin.ModelAdmin):
    raw_id_fields = ('field1',)
    list_display = ('field1', 'field2', 'field3',)
    actions = [
        export_csv_action("Export Sepecial Report",
            fields=[
                ('field1', 'label1'),
                ('foreign_key1__foreign_key2__name', 'label2'),
                ('field3', 'label3'),
            ],
            header=True
        ),
    ]
 
admin.site.register(ExampleMode, ExampleModelAdmin)

More like this

  1. Generic CSV export admin action factory with labels by losttrekker 3 years, 3 months ago
  2. Generic CSV export admin action factory with relationship spanning fields and labels, and many to many fields by selimnairb 1 year, 5 months ago
  3. More generic CSV export admin action factory by Rmatt 2 years ago
  4. Ultimate(?) export/download CSV admin action by anentropic 1 year, 9 months ago
  5. Generic admin action to export data into excel/csv by vinay.chittora 1 year, 11 months ago

Comments

selimnairb (on February 1, 2014):

Thanks. I've extended this to add support for writing all entries of many-to-many relationships as strings separated by a secondary delimiter. See here

#

Please login first before commenting.