Dépouillement

This commit is contained in:
Tom Hubrecht 2021-03-19 16:08:02 +01:00
parent 7c14c37d8a
commit 5beb1c25b3
4 changed files with 42 additions and 16 deletions

View file

@ -3,8 +3,13 @@ from django.contrib.auth.models import AbstractUser
from django.db import models from django.db import models
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from .staticdefs import CAST_FUNCTIONS, CONNECTION_METHODS, QUESTION_TYPES from .staticdefs import (
from .utils import CastFunctions, choices_length CAST_FUNCTIONS,
CONNECTION_METHODS,
QUESTION_TYPES,
TALLY_FUNCTIONS,
)
from .utils import CastFunctions, TallyFunctions, choices_length
# ############################################################################# # #############################################################################
# Models regarding an election # Models regarding an election
@ -76,6 +81,10 @@ class Question(models.Model):
cast_function = getattr(CastFunctions, CAST_FUNCTIONS[self.type]) cast_function = getattr(CastFunctions, CAST_FUNCTIONS[self.type])
cast_function(user, vote_form) cast_function(user, vote_form)
def tally(self):
tally_function = getattr(TallyFunctions, TALLY_FUNCTIONS[self.type])
tally_function(self)
class Meta: class Meta:
ordering = ["id"] ordering = ["id"]

View file

@ -33,3 +33,7 @@ VOTE_RULES = {
CAST_FUNCTIONS = { CAST_FUNCTIONS = {
"assentiment": "cast_select", "assentiment": "cast_select",
} }
TALLY_FUNCTIONS = {
"assentiment": "tally_select",
}

View file

@ -21,6 +21,7 @@ class CastFunctions:
"""Classe pour enregistrer les votes""" """Classe pour enregistrer les votes"""
def cast_select(user, vote_form): def cast_select(user, vote_form):
"""On enregistre un vote classique"""
vote_form.full_clean() vote_form.full_clean()
selected, n_selected = [], [] selected, n_selected = [], []
for v in vote_form: for v in vote_form:
@ -33,6 +34,27 @@ class CastFunctions:
user.votes.remove(*n_selected) 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): def create_users(election, csv_file):
"""Crée les votant·e·s pour l'élection donnée, en remplissant les champs """Crée les votant·e·s pour l'élection donnée, en remplissant les champs
`username`, `election` et `full_name`. `username`, `election` et `full_name`.

View file

@ -15,6 +15,7 @@ from django.views.generic import (
RedirectView, RedirectView,
UpdateView, UpdateView,
) )
from django.views.generic.detail import SingleObjectMixin
from .forms import ( from .forms import (
ElectionForm, ElectionForm,
@ -46,7 +47,7 @@ class BackgroundUpdateView(RedirectView):
success_message = self.get_success_message() success_message = self.get_success_message()
if success_message: if success_message:
messages.success(self.request, 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]) return reverse("election.admin", args=[self.object.pk])
class ElectionTallyView(CreatorOnlyEditMixin, BackgroundUpdateView): class ElectionTallyView(CreatorOnlyMixin, SingleObjectMixin, BackgroundUpdateView):
model = Election model = Election
pattern_name = "election.admin" pattern_name = "election.admin"
success_message = _("Élection dépouillée avec succès !") success_message = _("Élection dépouillée avec succès !")
@ -180,25 +181,15 @@ class ElectionTallyView(CreatorOnlyEditMixin, BackgroundUpdateView):
return ( return (
super() super()
.get_queryset() .get_queryset()
.filter(end_date__lt=timezone.now()) .filter(end_date__lt=timezone.now(), tallied=False)
.prefetch_related("questions__options") .prefetch_related("questions__options")
) )
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
election = self.get_object() election = self.get_object()
options, questions = [], []
for q in election.questions.all(): for q in election.questions.all():
max_votes = 0 q.tally()
for o in q.options.all():
o.nb_votes = o.voters.count()
max_votes = max(max_votes, o.nb_votes)
options.append(o)
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.tallied = True
election.save() election.save()
return super().get(request, *args, **kwargs) return super().get(request, *args, **kwargs)