From 275d79e28b9cff57297b167a5e4d528e849152b7 Mon Sep 17 00:00:00 2001
From: Dorian Lesbre <dorian.lesbre@gmail.com>
Date: Tue, 2 Mar 2021 18:08:34 +0100
Subject: [PATCH] Prettier (and more functionnal) admin website: - french names
 - export to csv action - display mutliple columns

---
 home/admin.py                 | 54 +++++++++++++++++++++++++++++++++--
 home/models.py                | 21 ++++++++++----
 home/templates/activites.html |  2 +-
 3 files changed, 68 insertions(+), 9 deletions(-)

diff --git a/home/admin.py b/home/admin.py
index f378059..6fac11e 100644
--- a/home/admin.py
+++ b/home/admin.py
@@ -1,7 +1,55 @@
+import csv
 from django.contrib import admin
+from django.http import HttpResponse
 
 from home.models import InterludesActivity, InterludesParticipant, ActivityList
 
-admin.site.register(InterludesActivity)
-admin.site.register(InterludesParticipant)
-admin.site.register(ActivityList)
+# Titre de la vue (objet <h1> dans le html)
+admin.site.site_header = "Administration site interludes"
+
+class ExportCsvMixin:
+	"""class abstraite pour permettre l'export CSV rapide d'un modele"""
+	def export_as_csv(self, request, queryset):
+		"""renvoie un fichier CSV contenant l'information du queryset"""
+		meta = self.model._meta
+		field_names = [field.name for field in meta.fields]
+
+		response = HttpResponse(content_type='text/csv')
+		response['Content-Disposition'] = 'attachment; filename={}.csv'.format(meta)
+		writer = csv.writer(response)
+
+		writer.writerow(field_names)
+		for obj in queryset:
+			writer.writerow([getattr(obj, field) for field in field_names])
+
+		return response
+
+	export_as_csv.short_description = "Exporter au format CSV"
+
+	actions = ["export_as_csv"]
+
+
+@admin.register(InterludesActivity)
+class InterludesActivityAdmin(admin.ModelAdmin, ExportCsvMixin):
+	"""option d'affichage des activités dans la vue django admin"""
+	list_display = ("title", "host_name", "display", "must_subscribe",)
+	list_filter = ("display", "must_subscribe",)
+	ordering = ("title", "host_name",)
+	list_editable = ("display",)
+	list_per_page = 100
+
+@admin.register(InterludesParticipant)
+class InterludesParticipantAdmin(admin.ModelAdmin, ExportCsvMixin):
+	"""option d'affichage des participant dans la vue django admin"""
+	list_display = ("name", "school",)
+	list_filter = ("school",)
+	ordering = ("name",)
+	list_per_page = 200
+
+@admin.register(ActivityList)
+class ActivityListAdmin(admin.ModelAdmin, ExportCsvMixin):
+	"""option d'affichage des choix d'activités dans la vue django admin"""
+	list_display = ("participant", "priority", "activity",)
+	list_filter = ("activity", "participant",)
+	ordering = ("participant", "priority",)
+	list_per_page = 200
diff --git a/home/models.py b/home/models.py
index d7531e7..05c4273 100644
--- a/home/models.py
+++ b/home/models.py
@@ -2,7 +2,6 @@ from django.contrib.auth.models import User
 from django.db import models
 from django.utils.translation import gettext_lazy as _
 
-# Create your models here.
 class InterludesActivity(models.Model):
 	"""une activité des interludes (i.e. JDR, murder)..."""
 	title = models.CharField("Titre", max_length=200)
@@ -14,7 +13,7 @@ class InterludesActivity(models.Model):
 		"Nombre minimum de participants"
 	)
 	display = models.BooleanField("Afficher cette activité", default=False)
-	must_book = models.BooleanField("Nécessite inscription", default=False)
+	must_subscribe = models.BooleanField("Sur inscription", default=False)
 	host_name = models.CharField("Nom de l'organisateur", max_length=50)
 	host_email = models.EmailField("Email de l'organisateur")
 	description = models.TextField("Description", max_length=2000)
@@ -28,6 +27,9 @@ class InterludesActivity(models.Model):
 	def __str__(self):
 		return self.title
 
+	class Meta:
+		verbose_name = "activité"
+
 
 class InterludesParticipant(models.Model):
 	"""un participant aux interludes"""
@@ -47,15 +49,24 @@ class InterludesParticipant(models.Model):
 	def __str__(self) -> str:
 		return "{} ({})".format(self.name, self.school)
 
+	class Meta:
+		verbose_name = "participant"
+
 
 class ActivityList(models.Model):
 	"""liste d'activités souhaitée de chaque participant,
 	avec un order de priorité"""
-	priority = models.PositiveIntegerField()
-	participant = models.ForeignKey(InterludesParticipant, on_delete=models.CASCADE)
-	activite = models.ForeignKey(InterludesActivity, on_delete=models.CASCADE)
+	priority = models.PositiveIntegerField("priorité")
+	participant = models.ForeignKey(
+		InterludesParticipant, on_delete=models.CASCADE, db_column="participant"
+	)
+	activity = models.ForeignKey(
+		InterludesActivity, on_delete=models.CASCADE, db_column="activité"
+	)
 
 	class Meta:
 		# le couple participant, priority est unique
 		unique_together = (("priority", "participant"))
 		ordering = ("participant", "priority")
+		verbose_name = "choix d'activités"
+		verbose_name_plural = "choix d'activités"
diff --git a/home/templates/activites.html b/home/templates/activites.html
index 5ea3ffb..9a629ad 100644
--- a/home/templates/activites.html
+++ b/home/templates/activites.html
@@ -15,7 +15,7 @@
 			<dt>Durée :</dt><dd>{{ activity.duration }}</dd>
 			<dt>MJ :</dt><dd>{{ activity.host_name }}</dd>
 			<dt>Nombre de places :</dt><dd>{{ activity.nb_participants }}</dd>
-			<dt>Sur inscription :</dt><dd>{% if activity.must_book %} Oui {% else %} Non {% endif %}</dd>
+			<dt>Sur inscription :</dt><dd>{% if activity.must_subscribe %} Oui {% else %} Non {% endif %}</dd>
 			<dt>Description :</dt><dd>{{ activity.description|linebreaksbr }}</dd>
 		</dl>
 	{% endfor %}
-- 
GitLab