CSV Ausgaben mit Django
Diese Dokumentation gilt für Djangos Entwicklerversion, die zum Teil erhebliche Unterschiede zur letzten veröffentlichen Version aufweist.
Dieses Dokument erklärt wie man mit Django-Views dynamisch CSV (Komma-separierte Werte, engl. Comma-separated values) ausgeben kann.
Du kannst dafür entweder das Python Modul csv oder das Django Template System benutzen.
Mit Hilfe des Python CSV Moduls
Python enthält standardmäßig das Modul csv. Wichtig für die Nutzung mit Django ist, dass das csv Modul CSV-Dateien aus dateiartigen Objekten erstellen kann, und dass Djangos HttpResponse-Objekt so ein dateiartiges Objekt ist.
Hinweis
Für weitere Informationen über das HttpResponse-Objekt, schau in die Request- und Response-Objekte Dokumentation.
Für weitere Informationen zum CSV Modul, schau in die CSV Modul Dokumentation.
Hier ist ein Beispiel:
import csv
from django.http import HttpResponse
def some_view(request):
# Erstelle das HttpResponse Objekt mit dem passenden CSV Header
response = HttpResponse(mimetype='text/csv')
response['Content-Disposition'] = 'attachment; filename=eindateiname.csv'
writer = csv.writer(response)
writer.writerow(['Erste Zeile', 'Foo', 'Bar', 'Baz'])
writer.writerow(['Zweite Zeile', 'A', 'B', 'C', '"Testen"', "Mit 'nem Apostroph"])
return response
Der Code und die Kommentare sollten selbsterklärend sein, aber ein paar Dinge verdienen eine Erwähnung:
- Das Response Objekt bekommt einen speziellen Mimetype, text/csv. Das teilt dem Browser mit, dass das Dokument eine CSV-Datei anstelle einer HTML-Datei ist. Wenn du das weglässt, könnten manche Browser die Ausgabe als HTML interpretieren und als hässliches, erschreckendes Kauderwelsch im Browserfenster darstellen.
- Das Response Objekt bekommt einen zusätzlichen Content-Disposition Header, der den Namen der CSV-Datei enthält. Dieser Dateiname ist willkürlich; benenne ihn wie immer du willst. Er wird vom Browser im “Speichern unter…” Dialogfenster, etc. gebraucht.
- Es ist einfach, die CSV API zu benutzen: Übergib einfach response als erstes Argument an csv.writer. Die csv.writer-Funktion erwartet ein dateiartiges Objekt und HttpResponse erfüllt diese Annahme.
- Rufe für jede Zeile in deiner CSV-Datei writer.writerow auf und übergib ein iterierbares Objekt, wie eine Liste oder ein Tuple.
- Das CSV-Modul überwacht Konflikte für dich, also brauchst du dir keine Sorgen über Strings mit Anführungszeichen oder Kommas zu machen. Übergib writerow() einfach deinen reinen String und es wird das Richtige tun.
Mit Hilfe von Django-Templates
Alternativ kannst du das Django-Templatesystem zur Generierung von CSV nutzen. Diese Möglichkeit ist ein niedrigeres Niveau als das praktische CSV Modul, wird hier aber der Vollständigkeit halber vorgestellt.
Die Grundidee hier ist, dass eine Liste von Dingen an dein Template übergeben wird. Im Template wird die Liste durch eine {% for %}-Schleife mit Kommas getrennt ausgegeben.
Hier ist ein Beispiel, welches die gleiche CSV-Datei erstellt wie oben:
from django.http import HttpResponse
from django.template import loader, Context
def some_view(request):
# Erstelle das HttpResponse Objekt mit dem passenden CSV Header
response = HttpResponse(mimetype='text/csv')
response['Content-Disposition'] = 'attachment; filename=eindateiname.csv'
# Diese Daten sind fest, aber du kannst sie aus einer Datenbank oder
# einer anderen Quelle laden.
csv_data = (
('Erste Zeile', 'Foo', 'Bar', 'Baz'),
('Zweite Zeile', 'A', 'B', 'C', '"Testen"', "Mit 'nem Apostroph"),
)
t = loader.get_template('mein_template_name.txt')
c = Context({
'data': csv_data,
})
response.write(t.render(c))
return response
Der einzige Unterschied zwischen diesem Beispiel und dem vorherigen ist, dass dieses ein Template anstelle des CSV Moduls lädt. Der Rest des Codes — wie mimetype='text/csv' — ist gleich.
Nun erstelle das Template mein_template_name.txt, mit diesem Template:
{% for row in data %}"{{ row.0|addslashes }}", "{{ row.1|addslashes }}", "{{ row.2|addslashes }}", "{{ row.3|addslashes }}", "{{ row.4|addslashes }}"
{% endfor %}
Dieses Template ist ziemlich einfach. Es iteriert nur über die gegebenen Daten und zeigt eine Zeile CSV für jede Datenzeile an. Es nutzt den addslashes Templatefilter, um sicher zustellen, dass es keine Probleme mit Anführungszeichen gibt. Wenn du dir sicher bist, dass deine Daten kein einziges einfaches oder doppeltes Anführungszeichen besitzen, kannst du den addslashes Filter entfernen.