Ce document explique comment générer du CSV (Comma Separated Values) dynamiquement en utilisant Django views. Pour cela, vous pouvez soit utiliser la bibliothèque CSV Python, soit utiliser le système de templates de Django.
Python est livré avec une bibliothèque CSV, csv. La clé pour l’utiliser avec Django est que le module csv agit sur des objets équivalents fichiers, et les objets HttpResponse de Django sont des objets équivalents fichiers.
Voici une exemple:
import csv
from django.http import HttpResponse
def some_view(request):
# Crée un objet HttpResponse avec l'entête CSV adéquat
response = HttpResponse(mimetype='text/csv')
response['Content-Disposition'] = 'attachment; filename=somefilename.csv'
writer = csv.writer(response)
writer.writerow(['First row', 'Foo', 'Bar', 'Baz'])
writer.writerow(['Second row', 'A', 'B', 'C', '"Testing"', "Here's a quote"])
return response
Le code et commentaires se comprennent d’eux-mêmes, mais quelques petites choses méritent qu’on s’y attarde:
Content-Disposition, qui contient le nom du fichier CSV. Ce nom de fichier est libre; appelez-le comme vous le voulez. Il sera utilisé par les navigateurs dans le dialogue “Enregistrer sous...”, etc.response en premier argument à csv.writer. La fonction csv.writer s’attends à un objet de type fichier, et les objets HttpResponse en sont.writer.writerow, en lui passant un objet itérable comme une liste ou un tuple.writerow(), et il fera ce qu’il faut.Le module Python csv ne supporte pas les entrées Unicode. Puisque Django utilise
Unicode en interne cela veut dire que les chaînes lues depuis des sources comme HttpRequest sont potentiellement problématiques. Il y a quelques solutions pour gérer cela:
UnicodeWriter fournie dans la `section exemples du module csv (lien en anglais)`_.csv et gère Unicode.Plus plus d’informations, voir la documentation Python du module csv.
Vous avez aussi la possibilité d’utiliser le Django template system
pour générer du CSV. C’est de plus bas niveau que l’utilisation du module Python csv, cette solution est présentée ici pour être complets.
Ici, l’idée est de passer une liste d’items à votre template, et que le template insère les virgules via une boucle for.
Voici un exemple qui génère le même fichier CSV que précédemment:
from django.http import HttpResponse
from django.template import loader, Context
def some_view(request):
# Crée l'objet HttpResponse avec l'entête CSV adéquat.
response = HttpResponse(mimetype='text/csv')
response['Content-Disposition'] = 'attachment; filename=somefilename.csv'
# Ici, les données sont codées en dur, mais vous pouvez les récupérer depuis une
# base de données ou depuis toute autre source.
csv_data = (
('First row', 'Foo', 'Bar', 'Baz'),
('Second row', 'A', 'B', 'C', '"Testing"', "Here's a quote"),
)
t = loader.get_template('my_template_name.txt')
c = Context({
'data': csv_data,
})
response.write(t.render(c))
return response
La seule différence entre cet exemple et le précédent est que celui-ci charge et utilise un template, au lieu du module CSV. Le reste du code – comme le mimetype='text/csv' – est identique.
Ensuite, créez un template my_template_name.txt, avec le code suivant:
{% for row in data %}"{{ row.0|addslashes }}", "{{ row.1|addslashes }}", "{{ row.2|addslashes }}", "{{ row.3|addslashes }}", "{{ row.4|addslashes }}"
{% endfor %}
Ce template est plutôt élémentaire. Il parcourt les données fournies et affiche une ligne CSV pour chaque rangée. Il utilise le filtre de template addslashes pour être sûr qu’il n’y ait pas de problèmes avec les guillemets.
Notez qu’il n’y a rien ici qui soit spécifique au CSV – juste le format de sortie adéquat. Vous pouvez utiliser l’une de ces techniques pour sortir tout format texte dont vous rêvez. Vous pouvez également utiliser une technique semblable pour générer des données binaires arbitraires; voir Outputting PDFs with Django pour un exemple.
Aug 13, 2017