From 9faa0b3354f4d0c08a1f6c79fa57aafa391f46ad Mon Sep 17 00:00:00 2001 From: Tom Hubrecht Date: Sun, 20 Dec 2020 10:35:18 +0100 Subject: [PATCH] Template changes and vote restriction for open elections --- elections/mixins.py | 16 ++++ elections/templates/elections/election.html | 73 ++++++++++++++++--- .../templates/elections/election_admin.html | 10 +-- .../templates/elections/election_list.html | 11 +-- elections/templates/elections/vote.html | 38 +++++++--- elections/views.py | 47 +++++------- 6 files changed, 134 insertions(+), 61 deletions(-) diff --git a/elections/mixins.py b/elections/mixins.py index c610533..314d923 100644 --- a/elections/mixins.py +++ b/elections/mixins.py @@ -35,6 +35,22 @@ class RestrictAccessMixin(SelectElectionMixin): return qs.none() +class OpenElectionOnly(RestrictAccessMixin): + """N'autorise la vue que lorsque l'élection est ouverte""" + + def get_filters(self): + f_prefix = self.get_f_prefix() + # On ne peut modifier que les élections qui n'ont pas commencé, et + # accessoirement qui ne sont pas dépouillées ou archivées + # TODO: décider si on choisit pas de juste garder les dates d'ouverture + filters = super().get_filters() + filters[f_prefix + "start_date__lt"] = timezone.now() + filters[f_prefix + "end_date__gt"] = timezone.now() + filters[f_prefix + "tallied"] = False + filters[f_prefix + "archived"] = False + return filters + + class CreatorOnlyMixin(RestrictAccessMixin): """Restreint l'accès au créateurice de l'élection""" diff --git a/elections/templates/elections/election.html b/elections/templates/elections/election.html index 8303dd3..4e45fd6 100644 --- a/elections/templates/elections/election.html +++ b/elections/templates/elections/election.html @@ -4,23 +4,74 @@ {% block content %} -

{{ election.name }}

+
+
+ {# Titre de l'élection #} +
+

{{ election.name }}

+
+ + {# Dates d'ouverture de l'élection #} +
+ {{ election.start_date|date:"d/m/Y H:i" }} + + + + {{ election.end_date|date:"d/m/Y H:i" }} +
+
+ + {% if election.start_date < current_time %} +
+
+ + {% if election.end_date < current_time %} + {% trans "Élection terminée" %} + {% else %} + {% trans "Élection en cours" %} + {% endif %} + +
+
+ {% endif %} +

-
-

{{ election.description }}

+{# Description de l'élection #} +
+
{{ election.description|linebreaksbr }}
-
- {% for q in questions %} -
-

{{ q.text }}

- {% for o in q.options.all %} - {{ o.text }}
- {% endfor %} - {% trans "Voter" %} +{# Liste des questions #} +{% for q in election.questions.all %} +
+
+ {% if election.start_date < current_time and election.end_date > current_time %} + + + + + {% trans "Voter" %} + + {% endif %} + {{ q.text }} +
+ + {# Liste des options possibles #} + {% for o in q.options.all %} +
+ {% if election.tallied and election.results_public %} + + + + + {{ o.nb_votes }} + + {% endif %} + {{ o.text }}
{% endfor %}
+{% endfor %} {% endblock %} diff --git a/elections/templates/elections/election_admin.html b/elections/templates/elections/election_admin.html index 8a2acac..4fa7ef8 100644 --- a/elections/templates/elections/election_admin.html +++ b/elections/templates/elections/election_admin.html @@ -117,16 +117,16 @@ -
   +
{% elif election.tallied %} {{ o.nb_votes }} -    + {% endif %} - {{ o.text }} + {{ o.text }}
{% endfor %} @@ -160,13 +160,13 @@
- +
- +
diff --git a/elections/templates/elections/election_list.html b/elections/templates/elections/election_list.html index f1596f8..c92e956 100644 --- a/elections/templates/elections/election_list.html +++ b/elections/templates/elections/election_list.html @@ -7,7 +7,7 @@
-

{% trans "Liste des élections créées" %}

+

{% trans "Liste des élections créées" %}

@@ -35,18 +35,15 @@ {{ e.end_date|date:"d/m/Y H:i" }} {% if e.tallied %} -   - {% trans "Élection dépouillée" %} + {% trans "Élection dépouillée" %} {% endif %} {% if e.results_public %} -   - {% trans "Élection publiée" %} + {% trans "Élection publiée" %} {% endif %} {% if e.archived %} -   - {% trans "Élection archivée" %} + {% trans "Élection archivée" %} {% endif %}
diff --git a/elections/templates/elections/vote.html b/elections/templates/elections/vote.html index 29ec391..82b1fd3 100644 --- a/elections/templates/elections/vote.html +++ b/elections/templates/elections/vote.html @@ -4,20 +4,36 @@ {% block content %} -

{% trans "Vote pour la question :" %} {{ question }}

+

{% trans "Vote pour la question :" %} {{ question.text }}

+
-
-
- {% csrf_token %} +
{% endblock %} diff --git a/elections/views.py b/elections/views.py index 382db22..477864d 100644 --- a/elections/views.py +++ b/elections/views.py @@ -1,6 +1,7 @@ from django.contrib import messages from django.contrib.messages.views import SuccessMessageMixin -from django.db.models import Count, Prefetch + +# from django.db.models import Count, Prefetch from django.http import HttpResponseRedirect from django.urls import reverse from django.utils import timezone @@ -15,7 +16,7 @@ from django.views.generic import ( ) from .forms import ElectionForm, OptionForm, OptionFormSet, QuestionForm -from .mixins import CreatorOnlyEditMixin, CreatorOnlyMixin +from .mixins import CreatorOnlyEditMixin, CreatorOnlyMixin, OpenElectionOnly from .models import Election, Option, Question # TODO: access control *everywhere* @@ -265,38 +266,30 @@ class ElectionView(DetailView): template_name = "elections/election.html" def get_context_data(self, **kwargs): - context = super().get_context_data(**kwargs) - if self.object.tallied: - options_qs = Option.objects.annotate(nb_votes=Count("voters")) - questions = self.election.question.prefetch_related( - Prefetch("options", queryset=options_qs) - ) - context["questions"] = questions - - return context + kwargs.update({"current_time": timezone.now()}) + return super().get_context_data(**kwargs) + # context = super().get_context_data(**kwargs) + # if self.object.tallied: + # options_qs = Option.objects.annotate(nb_votes=Count("voters")) + # questions = self.election.question.prefetch_related( + # Prefetch("options", queryset=options_qs) + # ) + # context["questions"] = questions + # return context def get_queryset(self): - return super().get_queryset().filter(archived=False) - - -class VoteView(SuccessMessageMixin, DetailView): - model = Question - template_name = "elections/vote.html" - - def get_queryset(self): - # On ne peut voter que si l'élection n'a pas été comptée return ( super() .get_queryset() - .filter( - election__tallied=False, - election__archived=False, - election__start_date__lt=timezone.now(), - election__end_date__gt=timezone.now(), - ) - .select_related("election") + .filter(archived=False) + .prefetch_related("questions__options") ) + +class VoteView(OpenElectionOnly, SuccessMessageMixin, DetailView): + model = Question + template_name = "elections/vote.html" + def get(self, request, *args, **kwargs): self.object = self.get_object() vote_form = OptionFormSet(instance=self.object)