Login

CSV Exporting of Model Data

Author:
monokrome
Posted:
November 11, 2009
Language:
Python
Version:
1.1
Score:
0 (after 0 ratings)

This is a basic model view for exporting data from models. It is designed so that you can provide the GET variables used for searching/filtering within listdisplay pages in the admin, and the code will filter the same way.

It allows the output of model data in various formats using serializers or templates.

 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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
from django.contrib.admin.options import IncorrectLookupParameters
from django.contrib.admin.views.main import ChangeList
from django.http import HttpResponse, HttpResponseForbidden, Http404
from django.core.serializers import serialize
from django.template import loader, RequestContext
from django.template.defaultfilters import slugify
from django.db.models.loading import get_model
from django.utils.encoding import smart_str
import csv

ALLOWED_EXPORT_TYPES = {
    'csv': {
        'mimetype': 'text/csv',
        'filename': '%s.csv',
        'template': 'admin/export/csv',
    },
    'json': {
        'mimetype': 'text/json',
        'filename': '%s.json',
        'serializer': 'json',
    },
    'xml': {
        'mimetype': 'text/xml',
        'filename': '%s.xml',
        'serializer': 'xml',
    },
    'yaml': {
        'mimetype': 'text/yaml',
        'filename': '%s.yaml',
        'serializer': 'yaml',
    },
    'py': {
        'mimetype': 'application/python',
        'filename': '%s.py',
        'serializer': 'python',
    }
}

def export(request, admin_site, model_name, app_label, format='csv'):
    if not request.user.is_staff:
        return HttpResponseForbidden()

    if not format in ALLOWED_EXPORT_TYPES:
        raise Http404('%s is not a supported format.' % format)

    model = get_model(app_label, model_name)
    model_admin = None

    for entry in admin_site._registry:
        if entry._meta.object_name == model._meta.object_name:
            model_admin = admin_site._registry[entry]

    if model_admin == None:
        raise Http404('ModelAdmin for model %s.%s not found' % (app_label, model_name))

    cl = ChangeList(request, model, list(model_admin.list_display), model_admin.list_display_links,
                    model_admin.list_filter, model_admin.date_hierarchy, model_admin.search_fields,
                    model_admin.list_select_related, model_admin.list_per_page, model_admin.list_editable,
                    model_admin)
    cl.formset = None

    c = RequestContext(request)
    if 'template' in ALLOWED_EXPORT_TYPES[format]:
        rows = []
        headers = []

        for field in model._meta.fields:
            headers.append(field.name)

        rows.append(headers)

        for record in cl.query_set:
            column = []

            for field in headers:
                val = getattr(record, field)

                if callable(val):
                    val = val()

                val = smart_str(val)
                column.append(val)

            rows.append(column)

        t = loader.get_template(ALLOWED_EXPORT_TYPES[format]['template'])
        c['rows'] = rows
        responseContents = t.render(c)
    elif 'serializer' in ALLOWED_EXPORT_TYPES[format]:
        responseContents = serialize(ALLOWED_EXPORT_TYPES[format]['serializer'], cl.query_set.all())
    else:
        raise Http404('Export type for %s must have value for template or serializer' % format)

    response = HttpResponse(responseContents, mimetype=ALLOWED_EXPORT_TYPES[format]['mimetype'])
    response['Content-Disposition'] = 'attachment; filename=%s' % (ALLOWED_EXPORT_TYPES[format]['filename'] % slugify(model_name))

    return response

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

Please login first before commenting.