Rajoute un lien pour exporter la liste des votant·e·s en csv
This commit is contained in:
parent
9d316a3044
commit
3c7598ffe4
5 changed files with 98 additions and 63 deletions
|
@ -28,7 +28,6 @@
|
||||||
<h1 class="title">{{ election.name }}</h1>
|
<h1 class="title">{{ election.name }}</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if election.start_date > current_time or election.end_date < current_time %}
|
|
||||||
<div class="level-right">
|
<div class="level-right">
|
||||||
<div class="level-item">
|
<div class="level-item">
|
||||||
<div class="dropdown is-right">
|
<div class="dropdown is-right">
|
||||||
|
@ -45,6 +44,14 @@
|
||||||
|
|
||||||
<div class="dropdown-menu" id="dropdown-menu" role="menu">
|
<div class="dropdown-menu" id="dropdown-menu" role="menu">
|
||||||
<div class="dropdown-content">
|
<div class="dropdown-content">
|
||||||
|
{# Téléchargement de la liste des votant·e·s #}
|
||||||
|
<a class="dropdown-item" href="{% url 'election.export-voters' election.pk %}">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fas fa-file-download"></i>
|
||||||
|
</span>
|
||||||
|
<span>{% trans "Exporter les votant·e·s" %}
|
||||||
|
</a>
|
||||||
|
|
||||||
{% if election.start_date > current_time %}
|
{% if election.start_date > current_time %}
|
||||||
{# Modification de l'élection #}
|
{# Modification de l'élection #}
|
||||||
<a class="dropdown-item" href="{% url 'election.update' election.pk %}">
|
<a class="dropdown-item" href="{% url 'election.update' election.pk %}">
|
||||||
|
@ -115,7 +122,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="level">
|
<div class="level">
|
||||||
|
|
|
@ -16,6 +16,11 @@ urlpatterns = [
|
||||||
views.ElectionUploadVotersView.as_view(),
|
views.ElectionUploadVotersView.as_view(),
|
||||||
name="election.upload-voters",
|
name="election.upload-voters",
|
||||||
),
|
),
|
||||||
|
path(
|
||||||
|
"export-voters/<int:pk>",
|
||||||
|
views.ExportVotersView.as_view(),
|
||||||
|
name="election.export-voters",
|
||||||
|
),
|
||||||
path(
|
path(
|
||||||
"delete-vote/<int:pk>/<int:user_pk>/<int:anchor>",
|
"delete-vote/<int:pk>/<int:user_pk>/<int:anchor>",
|
||||||
views.DeleteVoteView.as_view(),
|
views.DeleteVoteView.as_view(),
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
|
import csv
|
||||||
|
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.contrib.messages.views import SuccessMessageMixin
|
from django.contrib.messages.views import SuccessMessageMixin
|
||||||
from django.core.mail import EmailMessage
|
from django.core.mail import EmailMessage
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.http import Http404, HttpResponseRedirect
|
from django.http import Http404, HttpResponse, HttpResponseRedirect
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.decorators import method_decorator
|
from django.utils.decorators import method_decorator
|
||||||
|
@ -16,7 +18,9 @@ from django.views.generic import (
|
||||||
ListView,
|
ListView,
|
||||||
RedirectView,
|
RedirectView,
|
||||||
UpdateView,
|
UpdateView,
|
||||||
|
View,
|
||||||
)
|
)
|
||||||
|
from django.views.generic.detail import SingleObjectMixin
|
||||||
|
|
||||||
from .forms import (
|
from .forms import (
|
||||||
DeleteVoteForm,
|
DeleteVoteForm,
|
||||||
|
@ -107,6 +111,22 @@ class ElectionAdminView(CreatorOnlyMixin, DetailView):
|
||||||
return super().get_queryset().prefetch_related("questions__options")
|
return super().get_queryset().prefetch_related("questions__options")
|
||||||
|
|
||||||
|
|
||||||
|
class ExportVotersView(CreatorOnlyMixin, SingleObjectMixin, View):
|
||||||
|
model = Election
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
response = HttpResponse(content_type="text/csv")
|
||||||
|
|
||||||
|
writer = csv.writer(response)
|
||||||
|
response["Content-Disposition"] = "attachment; filename=voters.csv"
|
||||||
|
writer.writerow(["Nom", "login"])
|
||||||
|
|
||||||
|
for v in self.get_object().voters.all():
|
||||||
|
writer.writerow([v.full_name, v.username])
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
class ElectionUploadVotersView(CreatorOnlyEditMixin, SuccessMessageMixin, FormView):
|
class ElectionUploadVotersView(CreatorOnlyEditMixin, SuccessMessageMixin, FormView):
|
||||||
model = Election
|
model = Election
|
||||||
form_class = UploadVotersForm
|
form_class = UploadVotersForm
|
||||||
|
|
Binary file not shown.
|
@ -7,8 +7,8 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: 0.1\n"
|
"Project-Id-Version: 0.1\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-04-15 16:56+0200\n"
|
"POT-Creation-Date: 2021-04-15 22:50+0200\n"
|
||||||
"PO-Revision-Date: 2021-04-15 16:57+0200\n"
|
"PO-Revision-Date: 2021-04-15 22:55+0200\n"
|
||||||
"Last-Translator: Test Translator <test@translator>\n"
|
"Last-Translator: Test Translator <test@translator>\n"
|
||||||
"Language-Team: \n"
|
"Language-Team: \n"
|
||||||
"Language: en\n"
|
"Language: en\n"
|
||||||
|
@ -18,125 +18,125 @@ msgstr ""
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
"X-Generator: Poedit 2.4.1\n"
|
"X-Generator: Poedit 2.4.1\n"
|
||||||
|
|
||||||
#: elections/forms.py:29
|
#: elections/forms.py:19
|
||||||
msgid "Impossible de faire débuter l'élection dans le passé"
|
msgid "Impossible de faire débuter l'élection dans le passé"
|
||||||
msgstr "Impossible to start the election in the past"
|
msgstr "Impossible to start the election in the past"
|
||||||
|
|
||||||
#: elections/forms.py:33
|
#: elections/forms.py:23
|
||||||
msgid "Impossible de terminer l'élection avant de la commencer"
|
msgid "Impossible de terminer l'élection avant de la commencer"
|
||||||
msgstr "Impossible to end the election before it starts"
|
msgstr "Impossible to end the election before it starts"
|
||||||
|
|
||||||
#: elections/forms.py:56
|
#: elections/forms.py:46
|
||||||
msgid "Sélectionnez un fichier .csv"
|
msgid "Sélectionnez un fichier .csv"
|
||||||
msgstr "Select a .csv file"
|
msgstr "Select a .csv file"
|
||||||
|
|
||||||
#: elections/forms.py:66
|
#: elections/forms.py:56
|
||||||
msgid "Extension de fichier invalide, il faut un fichier au format CSV."
|
msgid "Extension de fichier invalide, il faut un fichier au format CSV."
|
||||||
msgstr "Invalid file extension, a CSV file is required."
|
msgstr "Invalid file extension, a CSV file is required."
|
||||||
|
|
||||||
#: elections/forms.py:100
|
#: elections/forms.py:90
|
||||||
msgid "Supprimer le vote de {} ({}) ?"
|
msgid "Supprimer le vote de {} ({}) ?"
|
||||||
msgstr "Delete the vote of {} ({}) ?"
|
msgstr "Delete the vote of {} ({}) ?"
|
||||||
|
|
||||||
#: elections/forms.py:105 elections/templates/elections/election_admin.html:168
|
#: elections/forms.py:95 elections/templates/elections/election_admin.html:174
|
||||||
#: elections/templates/elections/election_admin.html:195
|
#: elections/templates/elections/election_admin.html:201
|
||||||
#: elections/templates/elections/election_voters.html:57
|
#: elections/templates/elections/election_voters.html:57
|
||||||
msgid "Supprimer"
|
msgid "Supprimer"
|
||||||
msgstr "Delete"
|
msgstr "Delete"
|
||||||
|
|
||||||
#: elections/forms.py:105
|
#: elections/forms.py:95
|
||||||
msgid "Non"
|
msgid "Non"
|
||||||
msgstr "No"
|
msgstr "No"
|
||||||
|
|
||||||
#: elections/forms.py:105
|
#: elections/forms.py:95
|
||||||
msgid "Oui"
|
msgid "Oui"
|
||||||
msgstr "Yes"
|
msgstr "Yes"
|
||||||
|
|
||||||
#: elections/models.py:31
|
#: elections/models.py:30
|
||||||
msgid "nom"
|
msgid "nom"
|
||||||
msgstr "name"
|
msgstr "name"
|
||||||
|
|
||||||
#: elections/models.py:32
|
#: elections/models.py:31
|
||||||
msgid "nom bref"
|
msgid "nom bref"
|
||||||
msgstr "short name"
|
msgstr "short name"
|
||||||
|
|
||||||
#: elections/models.py:34
|
#: elections/models.py:33
|
||||||
msgid "description"
|
msgid "description"
|
||||||
msgstr "description"
|
msgstr "description"
|
||||||
|
|
||||||
#: elections/models.py:37
|
#: elections/models.py:36
|
||||||
msgid "date et heure de début"
|
msgid "date et heure de début"
|
||||||
msgstr "start date and time"
|
msgstr "start date and time"
|
||||||
|
|
||||||
#: elections/models.py:38
|
#: elections/models.py:37
|
||||||
msgid "date et heure de fin"
|
msgid "date et heure de fin"
|
||||||
msgstr "end date and time"
|
msgstr "end date and time"
|
||||||
|
|
||||||
#: elections/models.py:41
|
#: elections/models.py:40
|
||||||
msgid "conditions de vote"
|
msgid "conditions de vote"
|
||||||
msgstr "voting requirements"
|
msgstr "voting requirements"
|
||||||
|
|
||||||
#: elections/models.py:45
|
#: elections/models.py:44
|
||||||
msgid "restreint le vote à une liste de personnes"
|
msgid "restreint le vote à une liste de personnes"
|
||||||
msgstr "restricts the vote to a list of people"
|
msgstr "restricts the vote to a list of people"
|
||||||
|
|
||||||
#: elections/models.py:49
|
#: elections/models.py:48
|
||||||
msgid "mail avec les identifiants envoyé"
|
msgid "mail avec les identifiants envoyé"
|
||||||
msgstr "mail with credentials sent"
|
msgstr "mail with credentials sent"
|
||||||
|
|
||||||
#: elections/models.py:66
|
#: elections/models.py:65
|
||||||
msgid "résultats publics"
|
msgid "résultats publics"
|
||||||
msgstr "results published"
|
msgstr "results published"
|
||||||
|
|
||||||
#: elections/models.py:67
|
#: elections/models.py:66
|
||||||
msgid "dépouillée"
|
msgid "dépouillée"
|
||||||
msgstr "counted"
|
msgstr "counted"
|
||||||
|
|
||||||
#: elections/models.py:69
|
#: elections/models.py:68
|
||||||
msgid "archivée"
|
msgid "archivée"
|
||||||
msgstr "archived"
|
msgstr "archived"
|
||||||
|
|
||||||
#: elections/models.py:79
|
#: elections/models.py:78
|
||||||
msgid "question"
|
msgid "question"
|
||||||
msgstr "question"
|
msgstr "question"
|
||||||
|
|
||||||
#: elections/models.py:81
|
#: elections/models.py:80
|
||||||
msgid "type de question"
|
msgid "type de question"
|
||||||
msgstr "type of question"
|
msgstr "type of question"
|
||||||
|
|
||||||
#: elections/models.py:88
|
#: elections/models.py:87
|
||||||
msgid "nombre maximal de votes reçus"
|
msgid "nombre maximal de votes reçus"
|
||||||
msgstr "maximal number of votes received"
|
msgstr "maximal number of votes received"
|
||||||
|
|
||||||
#: elections/models.py:135
|
#: elections/models.py:134
|
||||||
msgid "texte"
|
msgid "texte"
|
||||||
msgstr "text"
|
msgstr "text"
|
||||||
|
|
||||||
#: elections/models.py:137
|
#: elections/models.py:136
|
||||||
msgid "option gagnante"
|
msgid "option gagnante"
|
||||||
msgstr "winning option"
|
msgstr "winning option"
|
||||||
|
|
||||||
#: elections/models.py:145
|
#: elections/models.py:144
|
||||||
msgid "nombre de votes reçus"
|
msgid "nombre de votes reçus"
|
||||||
msgstr "number of votes received"
|
msgstr "number of votes received"
|
||||||
|
|
||||||
#: elections/models.py:164
|
#: elections/models.py:163
|
||||||
msgid "rang de l'option"
|
msgid "rang de l'option"
|
||||||
msgstr "option's ranking"
|
msgstr "option's ranking"
|
||||||
|
|
||||||
#: elections/models.py:180
|
#: elections/models.py:179
|
||||||
msgid "votes supplémentaires"
|
msgid "votes supplémentaires"
|
||||||
msgstr "extra votes"
|
msgstr "extra votes"
|
||||||
|
|
||||||
#: elections/models.py:196
|
#: elections/models.py:195
|
||||||
msgid "Nom et Prénom"
|
msgid "Nom et Prénom"
|
||||||
msgstr "Name and surname"
|
msgstr "Name and surname"
|
||||||
|
|
||||||
#: elections/models.py:218 elections/tests/test_models.py:57
|
#: elections/models.py:217 elections/tests/test_models.py:57
|
||||||
msgid "identifiants spécifiques"
|
msgid "identifiants spécifiques"
|
||||||
msgstr "dedicated credentials"
|
msgstr "dedicated credentials"
|
||||||
|
|
||||||
#: elections/models.py:222
|
#: elections/models.py:221
|
||||||
msgid "Peut administrer des élections"
|
msgid "Peut administrer des élections"
|
||||||
msgstr "Can manage elections"
|
msgstr "Can manage elections"
|
||||||
|
|
||||||
|
@ -285,49 +285,53 @@ msgstr "Login via CAS"
|
||||||
msgid "A voté"
|
msgid "A voté"
|
||||||
msgstr "Voted"
|
msgstr "Voted"
|
||||||
|
|
||||||
#: elections/templates/elections/election_admin.html:41
|
#: elections/templates/elections/election_admin.html:40
|
||||||
msgid "Actions"
|
msgid "Actions"
|
||||||
msgstr "Actions"
|
msgstr "Actions"
|
||||||
|
|
||||||
#: elections/templates/elections/election_admin.html:54
|
#: elections/templates/elections/election_admin.html:52
|
||||||
#: elections/templates/elections/election_admin.html:177
|
msgid "Exporter les votant·e·s"
|
||||||
#: elections/templates/elections/election_admin.html:200
|
msgstr "Export the list of voters"
|
||||||
|
|
||||||
|
#: elections/templates/elections/election_admin.html:61
|
||||||
|
#: elections/templates/elections/election_admin.html:183
|
||||||
|
#: elections/templates/elections/election_admin.html:206
|
||||||
msgid "Modifier"
|
msgid "Modifier"
|
||||||
msgstr "Edit"
|
msgstr "Edit"
|
||||||
|
|
||||||
#: elections/templates/elections/election_admin.html:63
|
#: elections/templates/elections/election_admin.html:70
|
||||||
#: elections/templates/elections/upload_voters.html:25
|
#: elections/templates/elections/upload_voters.html:25
|
||||||
msgid "Gestion de la liste de votant·e·s"
|
msgid "Gestion de la liste de votant·e·s"
|
||||||
msgstr "Management of the voters' list"
|
msgstr "Management of the voters' list"
|
||||||
|
|
||||||
#: elections/templates/elections/election_admin.html:75
|
#: elections/templates/elections/election_admin.html:82
|
||||||
#: elections/templates/elections/election_voters.html:27
|
#: elections/templates/elections/election_voters.html:27
|
||||||
msgid "Liste des votant·e·s"
|
msgid "Liste des votant·e·s"
|
||||||
msgstr "Voters' list"
|
msgstr "Voters' list"
|
||||||
|
|
||||||
#: elections/templates/elections/election_admin.html:83
|
#: elections/templates/elections/election_admin.html:90
|
||||||
msgid "Dépouiller"
|
msgid "Dépouiller"
|
||||||
msgstr "Count"
|
msgstr "Count"
|
||||||
|
|
||||||
#: elections/templates/elections/election_admin.html:94
|
#: elections/templates/elections/election_admin.html:101
|
||||||
msgid "Publier"
|
msgid "Publier"
|
||||||
msgstr "Publish"
|
msgstr "Publish"
|
||||||
|
|
||||||
#: elections/templates/elections/election_admin.html:96
|
#: elections/templates/elections/election_admin.html:103
|
||||||
msgid "Dépublier"
|
msgid "Dépublier"
|
||||||
msgstr "De-publish"
|
msgstr "De-publish"
|
||||||
|
|
||||||
#: elections/templates/elections/election_admin.html:106
|
#: elections/templates/elections/election_admin.html:113
|
||||||
msgid "Archiver"
|
msgid "Archiver"
|
||||||
msgstr "Archive"
|
msgstr "Archive"
|
||||||
|
|
||||||
#: elections/templates/elections/election_admin.html:243
|
#: elections/templates/elections/election_admin.html:249
|
||||||
#: elections/templates/elections/election_admin.html:254
|
#: elections/templates/elections/election_admin.html:260
|
||||||
msgid "Rajouter une option"
|
msgid "Rajouter une option"
|
||||||
msgstr "Add an option"
|
msgstr "Add an option"
|
||||||
|
|
||||||
#: elections/templates/elections/election_admin.html:258
|
#: elections/templates/elections/election_admin.html:264
|
||||||
#: elections/templates/elections/election_admin.html:268
|
#: elections/templates/elections/election_admin.html:274
|
||||||
msgid "Rajouter une question"
|
msgid "Rajouter une question"
|
||||||
msgstr "Add a question"
|
msgstr "Add a question"
|
||||||
|
|
||||||
|
@ -535,55 +539,55 @@ msgstr "Missing value in line {}: 'name'."
|
||||||
msgid "Adresse mail invalide à la ligne {} : '{}'."
|
msgid "Adresse mail invalide à la ligne {} : '{}'."
|
||||||
msgstr "Invalid e-mail address in line {}: '{}'."
|
msgstr "Invalid e-mail address in line {}: '{}'."
|
||||||
|
|
||||||
#: elections/views.py:69
|
#: elections/views.py:73
|
||||||
msgid "Élection créée avec succès !"
|
msgid "Élection créée avec succès !"
|
||||||
msgstr "Election successfully created!"
|
msgstr "Election successfully created!"
|
||||||
|
|
||||||
#: elections/views.py:113
|
#: elections/views.py:133
|
||||||
msgid "Liste de votant·e·s importée avec succès !"
|
msgid "Liste de votant·e·s importée avec succès !"
|
||||||
msgstr "Voters list successfully imported!"
|
msgstr "Voters list successfully imported!"
|
||||||
|
|
||||||
#: elections/views.py:147
|
#: elections/views.py:167
|
||||||
msgid "Mail d'annonce envoyé avec succès !"
|
msgid "Mail d'annonce envoyé avec succès !"
|
||||||
msgstr "Announcement e-mail sent successfully!"
|
msgstr "Announcement e-mail sent successfully!"
|
||||||
|
|
||||||
#: elections/views.py:179
|
#: elections/views.py:199
|
||||||
msgid "Élection modifiée avec succès !"
|
msgid "Élection modifiée avec succès !"
|
||||||
msgstr "Election successfully modified!"
|
msgstr "Election successfully modified!"
|
||||||
|
|
||||||
#: elections/views.py:249
|
#: elections/views.py:269
|
||||||
msgid "Élection dépouillée avec succès !"
|
msgid "Élection dépouillée avec succès !"
|
||||||
msgstr "Election successfully counted!"
|
msgstr "Election successfully counted!"
|
||||||
|
|
||||||
#: elections/views.py:275
|
#: elections/views.py:295
|
||||||
msgid "Élection publiée avec succès !"
|
msgid "Élection publiée avec succès !"
|
||||||
msgstr "Election successfully published!"
|
msgstr "Election successfully published!"
|
||||||
|
|
||||||
#: elections/views.py:276
|
#: elections/views.py:296
|
||||||
msgid "Élection dépubliée avec succès !"
|
msgid "Élection dépubliée avec succès !"
|
||||||
msgstr "Election successfully de-published!"
|
msgstr "Election successfully de-published!"
|
||||||
|
|
||||||
#: elections/views.py:288
|
#: elections/views.py:308
|
||||||
msgid "Élection archivée avec succès !"
|
msgid "Élection archivée avec succès !"
|
||||||
msgstr "Election successfully archived!"
|
msgstr "Election successfully archived!"
|
||||||
|
|
||||||
#: elections/views.py:320
|
#: elections/views.py:340
|
||||||
msgid "Question modifiée avec succès !"
|
msgid "Question modifiée avec succès !"
|
||||||
msgstr "Question successfully modified!"
|
msgstr "Question successfully modified!"
|
||||||
|
|
||||||
#: elections/views.py:332
|
#: elections/views.py:352
|
||||||
msgid "Question supprimée !"
|
msgid "Question supprimée !"
|
||||||
msgstr "Question deleted!"
|
msgstr "Question deleted!"
|
||||||
|
|
||||||
#: elections/views.py:370
|
#: elections/views.py:390
|
||||||
msgid "Option modifiée avec succès !"
|
msgid "Option modifiée avec succès !"
|
||||||
msgstr "Option successfully modified!"
|
msgstr "Option successfully modified!"
|
||||||
|
|
||||||
#: elections/views.py:382
|
#: elections/views.py:402
|
||||||
msgid "Option supprimée !"
|
msgid "Option supprimée !"
|
||||||
msgstr "Option deleted!"
|
msgstr "Option deleted!"
|
||||||
|
|
||||||
#: elections/views.py:522
|
#: elections/views.py:542
|
||||||
msgid "Votre choix a bien été enregistré !"
|
msgid "Votre choix a bien été enregistré !"
|
||||||
msgstr "Your choice has been recorded!"
|
msgstr "Your choice has been recorded!"
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue