Add a view to see the list of ballots
This commit is contained in:
parent
2397fdb715
commit
1cdb125356
6 changed files with 109 additions and 0 deletions
|
@ -14,6 +14,7 @@ from .staticdefs import (
|
||||||
VALIDATE_FUNCTIONS,
|
VALIDATE_FUNCTIONS,
|
||||||
)
|
)
|
||||||
from .utils import (
|
from .utils import (
|
||||||
|
BallotsData,
|
||||||
CastFunctions,
|
CastFunctions,
|
||||||
ResultsData,
|
ResultsData,
|
||||||
TallyFunctions,
|
TallyFunctions,
|
||||||
|
@ -116,6 +117,10 @@ class Question(models.Model):
|
||||||
results_function = getattr(ResultsData, BALLOT_TYPE[self.type])
|
results_function = getattr(ResultsData, BALLOT_TYPE[self.type])
|
||||||
return results_function(self)
|
return results_function(self)
|
||||||
|
|
||||||
|
def display_ballots(self):
|
||||||
|
display_function = getattr(BallotsData, BALLOT_TYPE[self.type])
|
||||||
|
return display_function(self)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def vote_type(self):
|
def vote_type(self):
|
||||||
return BALLOT_TYPE[self.type]
|
return BALLOT_TYPE[self.type]
|
||||||
|
|
25
elections/templates/elections/ballots/select.html
Normal file
25
elections/templates/elections/ballots/select.html
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
{% for o in options %}
|
||||||
|
<th>{{ o }}</th>
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
{% for ballot in ballots.values %}
|
||||||
|
<tr>
|
||||||
|
{% for v in ballot %}
|
||||||
|
<td class="has-text-centered">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fas fa-{% if v %}check{% else %}times{% endif %}"></i>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
36
elections/templates/elections/election_ballots.html
Normal file
36
elections/templates/elections/election_ballots.html
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="level">
|
||||||
|
{# Titre de l'élection #}
|
||||||
|
<div class="level-left is-flex-shrink-1">
|
||||||
|
<h1 class="title">{{ election.name }}</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="level-right">
|
||||||
|
<div class="level-item">
|
||||||
|
<a class="button is-primary" href="{% url 'election.view' election.pk %}">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fas fa-undo-alt"></i>
|
||||||
|
</span>
|
||||||
|
<span>{% trans "Retour" %}</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="level">
|
||||||
|
<div class="level-left">
|
||||||
|
<h3 class="subtitle">{% trans "Liste des bulletins" %}</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
{# Tableau des bulletins par question #}
|
||||||
|
{% for q in election.questions.all %}
|
||||||
|
{{ q.display_ballots }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% endblock %}
|
|
@ -76,5 +76,10 @@ urlpatterns = [
|
||||||
views.ElectionVotersView.as_view(),
|
views.ElectionVotersView.as_view(),
|
||||||
name="election.voters",
|
name="election.voters",
|
||||||
),
|
),
|
||||||
|
path(
|
||||||
|
"view/<int:pk>/ballots",
|
||||||
|
views.ElectionBallotsView.as_view(),
|
||||||
|
name="election.ballots",
|
||||||
|
),
|
||||||
path("vote/<int:pk>", views.VoteView.as_view(), name="election.vote"),
|
path("vote/<int:pk>", views.VoteView.as_view(), name="election.vote"),
|
||||||
]
|
]
|
||||||
|
|
|
@ -271,6 +271,31 @@ class ResultsData:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class BallotsData:
|
||||||
|
"""Classe pour afficher les bulletins d'une question"""
|
||||||
|
|
||||||
|
def select(question):
|
||||||
|
from .models import Vote
|
||||||
|
|
||||||
|
votes = Vote.objects.filter(option__question=question)
|
||||||
|
|
||||||
|
options = list(question.options.all())
|
||||||
|
|
||||||
|
ballots = {}
|
||||||
|
for v in votes:
|
||||||
|
ballot = ballots.get(v.user, [False] * len(options))
|
||||||
|
ballot[options.index(v.option)] = True
|
||||||
|
|
||||||
|
ballots[v.user] = ballot
|
||||||
|
|
||||||
|
return render_to_string(
|
||||||
|
"elections/ballots/select.html", {"options": options, "ballots": ballots}
|
||||||
|
)
|
||||||
|
|
||||||
|
def rank(question):
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
# #############################################################################
|
# #############################################################################
|
||||||
# Fonctions pour importer une liste de votant·e·s
|
# Fonctions pour importer une liste de votant·e·s
|
||||||
# #############################################################################
|
# #############################################################################
|
||||||
|
|
|
@ -479,6 +479,19 @@ class ElectionVotersView(NotArchivedMixin, DetailView):
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
class ElectionBallotsView(NotArchivedMixin, DetailView):
|
||||||
|
model = Election
|
||||||
|
template_name = "elections/election_ballots.html"
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return (
|
||||||
|
super()
|
||||||
|
.get_queryset()
|
||||||
|
.filter(tallied=True)
|
||||||
|
.prefetch_related("questions__options")
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class VoteView(OpenElectionOnlyMixin, DetailView):
|
class VoteView(OpenElectionOnlyMixin, DetailView):
|
||||||
model = Question
|
model = Question
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue