Login

More generic CSV export admin action factory

Author:
Rmatt
Posted:
June 25, 2013
Language:
Python
Version:
1.4
Score:
0 (after 0 ratings)

based on #2020

This one is even more generic than the previous generic ones since you can specify in fields any attribute you will give to the admin interface and not just fields from the model.

You can for example directly export the list_display as a list of fields, including look-ups for related attributes that you may have defined in a function inside the Admin Class

 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
import csv
from django.http import HttpResponse

def export_as_csv_action(description="Export selected objects as CSV file",
                         fields=None, exclude=None, header=True, force_fields=None):
    """
    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
    if 'force_field' is True, you can give as a list of string whatever django admin can read in display_list
    else it will check if the fields are in the model and reduce the list
    """
    def export_as_csv(modeladmin, request, queryset):
        """
        Generic csv export admin action.
        based on http://djangosnippets.org/snippets/2020/
        extended for being able to give list_display as fields and work with admin-defined functions
        """
        opts = modeladmin.model._meta
        if not force_fields:
            field_names = set([field.name for field in opts.fields])
            if fields:
                fieldset = set(fields)
                field_names = field_names & fieldset
        elif fields:
            field_names = set(fields)
        else:
            raise("option force_fields can only be used in parallel with option fields")
        if exclude:
            excludeset = set(exclude)
            field_names = field_names - excludeset

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

        writer = csv.writer(response)
        if header:
            writer.writerow(list(field_names))
        for obj in queryset:
            row = []
            for field in field_names:
                try:
                    row.append(unicode(getattr(obj, field)).encode('utf-8'))
                except AttributeError:
                    row.append(unicode((getattr(modeladmin, field)(obj))).encode('utf-8'))
                except:
                    raise
            writer.writerow(row)
        return response
    export_as_csv.short_description = description
    return export_as_csv


# example usage:

class SubscriberAdmin(admin.ModelAdmin):

    def display_city(self, obj):
        return obj.address.city #address being i.e. a OneToOne relation to Subscriber

    raw_id_fields = ('logged_in_as',)
    list_display = ('email', 'date', 'logged_in_as', 'display_city',)
    actions = [export_as_csv_action("Export selected emails as CSV file", fields=list_display, header=True, force_fields=True),]

admin.site.register(UpdatesSubscriber, SubscriberAdmin)

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 11 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 11 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 6 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 7 months ago
  5. Help text hyperlinks by sa2812 1 year, 7 months ago

Comments

kevinguru (on August 1, 2013):

Thanks for nice work!

Modern Design Furniture

#

Please login first before commenting.