kadenios/elections/views.py

129 lines
4.2 KiB
Python

from django.contrib import messages
from django.contrib.messages.views import SuccessMessageMixin
from django.db.models import Count, Prefetch
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from django.views.generic import CreateView, DetailView, RedirectView, UpdateView
from django.views.generic.detail import SingleObjectMixin
from .forms import OptionFormSet
from .models import Election, Option, Question
# TODO: access control *everywhere*
class ElectionCreateView(SuccessMessageMixin, CreateView):
model = Election
fields = ["name", "description", "start_date", "end_date"]
template_name = "elections/election_create.html"
success_message = _("Élection crée avec succès !")
# TODO : only the creator can edit the election and view the admin panel
class ElectionAdminView(DetailView):
model = Election
template_name = "elections/election_admin.html"
def get_context_data(self, **kwargs):
kwargs.update({"current_time": timezone.now()})
return super().get_context_data(**kwargs)
def get_queryset(self):
return super().get_queryset().prefetch_related("questions__options")
class ElectionUpdateView(SuccessMessageMixin, UpdateView):
model = Election
fields = ["name", "description", "start_date", "end_date"]
success_message = _("Élection modifiée avec succès !")
template_name = "elections/election_update.html"
def get_success_url(self):
return reverse("election.admin", args=[self.object.pk])
def get_queryset(self):
# On ne peut plus modifier une élection déjà comptée
return super().get_queryset().filter(tallied=False, archived=False)
class ElectionTallyView(SuccessMessageMixin, SingleObjectMixin, RedirectView):
model = Election
def get(self, request, *args, **kwargs):
election = self.get_object()
election.update(tallied=True)
return super().get(request, *args, **kwargs)
class ElectionPublishView(SuccessMessageMixin, SingleObjectMixin, RedirectView):
model = Election
def get(self, request, *args, **kwargs):
election = self.get_object()
election.update(tallied=True)
return super().get(request, *args, **kwargs)
class ElectionArchiveView(SuccessMessageMixin, SingleObjectMixin, RedirectView):
model = Election
def get(self, request, *args, **kwargs):
election = self.get_object()
election.update(tallied=True)
return super().get(request, *args, **kwargs)
class ElectionView(DetailView):
model = Election
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
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)
.select_related("election")
)
def get(self, request, *args, **kwargs):
self.object = self.get_object()
vote_form = OptionFormSet(instance=self.object)
return self.render_to_response(self.get_context_data(formset=vote_form))
def post(self, request, *args, **kwargs):
self.object = self.get_object()
vote_form = OptionFormSet(self.request.POST, instance=self.object)
# We record the cast votes
for v in vote_form:
v.record_vote(self.request.user)
messages.success(self.request, _("Votre vote a bien été enregistré !"))
return HttpResponseRedirect(
reverse("election.view", args=[self.object.election.pk])
+ f"#q_{self.object.pk}"
)