Makina Blog
Comment facilement exporter en CSV depuis l'admin Django
La possibilité d'exporter en CSV est une demande fréquente. Grâce à l'admin Django, nous pouvons mettre cela en place très facilement, comme nous allons le voir dans cet article.
Nous utiliserons deux choses pour arriver à notre fin. Tout d'abord, la bibliothèque csv standard, qui nous offre la possibilité de facilement créer un CSV :
import csv
writer = csv.writer(csvfile)
writer.writerow(['une colonne', 'une seconde colonne'])
Django permet de créer une réponse HTTP utilisant ceci très facilement, tout est expliqué en détail dans la documentation officielle :
import csv
from django.http import HttpResponse
def some_view(request):
# Create the HttpResponse object with the appropriate CSV header.
response = HttpResponse(
content_type='text/csv',
headers={'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
Puis pour l'intégrer dans l'admin, nous implémenterons une action :
from django.contrib import admin
from django.utils.translation import gettext_lazy as _
class UserAdmin(admin.ModelAdmin):
actions = ['export_csv']
@admin.action(description=_('Exporter en CSV'))
def export_csv(self, request, queryset):
[...]
Les actions permettent de travailler sur les objets sélectionnés dans la liste. Si une action retourne une réponse HTTP, alors c'est cette réponse qui sera renvoyée au navigateur ! En utilisant ce que nous savons désormais, et en combinant tout ça, nous avons déjà notre solution :
import csv
from django.contrib import admin
from django.http import HttpResponse
from django.utils.translation import gettext_lazy as _
class UserAdmin(admin.ModelAdmin):
actions = ['export_csv']
@admin.action(description=_('Exporter en CSV'))
def export_csv(self, request, queryset):
response = HttpResponse(
content_type='text/csv',
headers={'Content-Disposition': 'attachment; filename="utilisateurs.csv"'},
)
writer = csv.writer(response)
for user in queryset:
writer.writerow([
user.id,
user.username,
user.email,
user.first_name,
user.last_name,
])
return response
Il suffit ensuite de sélectionner les éléments que nous voulons exporter, de choisir l'action d'export, puis de cliquer sur le bouton. Pour tout exporter, nous pouvons cliquer sur la case en haut à gauche, puis cliquer sur "Sélectionner tous les X éléments" si nous avons plusieurs pages :
Et voila, à nous les CSV sans effort, merci Django 😊 !
Edit: Merci à Jean-Philippe Vincent de nous avoir fait part de sa méthode, pratique si l'on veut exporter tous les champs sans se prendre la tête :
writer.writerow([key for key, value in queryset.values()[0].items()])
writer.writerows(queryset.values_list())
Ou, préférence de ma part pour garder la main sur les données exportées :
writer.writerow(['id', 'username', 'email'])
writer.writerows(queryset.values_list(['id', 'username', 'email']))
Cette méthode a en plus l'avantage de limiter la requête SQL et ne pas instancier les objets, ce qui n'est pas négligeable en terme de performance.
Formations associées
Formations Django
Formation Django avancé
À distance (FOAD) Du 9 au 13 décembre 2024
Voir la formationActualités en lien
Présentation de django-tracking-fields
Suivi de modification d'objets Django
Internationalisation avec Django
En tant que développeurs nous sommes parfois confronté à la problématique de l'accessibilité des utilisateurs parlant différentes langues. Cet article est à destination des développeurs Django souhaitant découvrir l'internationalisation (i18n) et propose un parcours pas à pas dans cet exercice.
Présentation de Django-Safedelete
Masquage d'objets en base de données une alternative à la suppression définitive.