diff --git a/elections/models.py b/elections/models.py index f20c20a..1416658 100644 --- a/elections/models.py +++ b/elections/models.py @@ -3,8 +3,13 @@ from django.contrib.auth.models import AbstractUser from django.db import models from django.utils.translation import gettext_lazy as _ -from .staticdefs import CAST_FUNCTIONS, CONNECTION_METHODS, QUESTION_TYPES -from .utils import CastFunctions, choices_length +from .staticdefs import ( + CAST_FUNCTIONS, + CONNECTION_METHODS, + QUESTION_TYPES, + TALLY_FUNCTIONS, +) +from .utils import CastFunctions, TallyFunctions, choices_length # ############################################################################# # Models regarding an election @@ -76,6 +81,10 @@ class Question(models.Model): cast_function = getattr(CastFunctions, CAST_FUNCTIONS[self.type]) cast_function(user, vote_form) + def tally(self): + tally_function = getattr(TallyFunctions, TALLY_FUNCTIONS[self.type]) + tally_function(self) + class Meta: ordering = ["id"] diff --git a/elections/staticdefs.py b/elections/staticdefs.py index d0d5f16..d9e3da5 100644 --- a/elections/staticdefs.py +++ b/elections/staticdefs.py @@ -33,3 +33,7 @@ VOTE_RULES = { CAST_FUNCTIONS = { "assentiment": "cast_select", } + +TALLY_FUNCTIONS = { + "assentiment": "tally_select", +} diff --git a/elections/utils.py b/elections/utils.py index f3edaa3..ec16312 100644 --- a/elections/utils.py +++ b/elections/utils.py @@ -21,6 +21,7 @@ class CastFunctions: """Classe pour enregistrer les votes""" def cast_select(user, vote_form): + """On enregistre un vote classique""" vote_form.full_clean() selected, n_selected = [], [] for v in vote_form: @@ -33,6 +34,27 @@ class CastFunctions: user.votes.remove(*n_selected) +class TallyFunctions: + """Classe pour gérer les dépouillements""" + + def tally_select(question): + """On dépouille un vote classique""" + from .models import Option + + max_votes = 0 + options = [] + + for o in question.options.prefetch_related("voters").all(): + o.nb_votes = o.voters.count() + max_votes = max(max_votes, o.nb_votes) + options.append(o) + + question.max_votes = max_votes + question.save() + + Option.objects.bulk_update(options, ["nb_votes"]) + + def create_users(election, csv_file): """Crée les votant·e·s pour l'élection donnée, en remplissant les champs `username`, `election` et `full_name`. diff --git a/elections/views.py b/elections/views.py index dd28222..e48dee3 100644 --- a/elections/views.py +++ b/elections/views.py @@ -15,6 +15,7 @@ from django.views.generic import ( RedirectView, UpdateView, ) +from django.views.generic.detail import SingleObjectMixin from .forms import ( ElectionForm, @@ -46,7 +47,7 @@ class BackgroundUpdateView(RedirectView): success_message = self.get_success_message() if success_message: messages.success(self.request, success_message) - return super().get(self, request, *args, **kwargs) + return super().get(request, *args, **kwargs) # ############################################################################# @@ -171,7 +172,7 @@ class ElectionUpdateView(CreatorOnlyEditMixin, SuccessMessageMixin, UpdateView): return reverse("election.admin", args=[self.object.pk]) -class ElectionTallyView(CreatorOnlyEditMixin, BackgroundUpdateView): +class ElectionTallyView(CreatorOnlyMixin, SingleObjectMixin, BackgroundUpdateView): model = Election pattern_name = "election.admin" success_message = _("Élection dépouillée avec succès !") @@ -180,25 +181,15 @@ class ElectionTallyView(CreatorOnlyEditMixin, BackgroundUpdateView): return ( super() .get_queryset() - .filter(end_date__lt=timezone.now()) + .filter(end_date__lt=timezone.now(), tallied=False) .prefetch_related("questions__options") ) def get(self, request, *args, **kwargs): election = self.get_object() - options, questions = [], [] for q in election.questions.all(): - max_votes = 0 - for o in q.options.all(): - o.nb_votes = o.voters.count() - max_votes = max(max_votes, o.nb_votes) - options.append(o) + q.tally() - q.max_votes = max_votes - questions.append(q) - - Option.objects.bulk_update(options, ["nb_votes"]) - Question.objects.bulk_update(questions, ["max_votes"]) election.tallied = True election.save() return super().get(request, *args, **kwargs)