On restreint l'accès au vote
This commit is contained in:
parent
5865583ace
commit
e704e2a155
7 changed files with 128 additions and 24 deletions
|
@ -21,7 +21,7 @@ class ElectionForm(forms.ModelForm):
|
|||
|
||||
class Meta:
|
||||
model = Election
|
||||
fields = ["name", "description", "start_date", "end_date"]
|
||||
fields = ["name", "description", "restricted", "start_date", "end_date"]
|
||||
|
||||
|
||||
class QuestionForm(forms.ModelForm):
|
||||
|
|
36
elections/migrations/0002_auto_20201220_1735.py
Normal file
36
elections/migrations/0002_auto_20201220_1735.py
Normal file
|
@ -0,0 +1,36 @@
|
|||
# Generated by Django 2.2.17 on 2020-12-20 16:35
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("elections", "0001_initial"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="user",
|
||||
name="election",
|
||||
field=models.ForeignKey(
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="registered_voters",
|
||||
to="elections.Election",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="election",
|
||||
name="created_by",
|
||||
field=models.ForeignKey(
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
related_name="elections_created",
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
),
|
||||
),
|
||||
]
|
20
elections/migrations/0003_election_restricted.py
Normal file
20
elections/migrations/0003_election_restricted.py
Normal file
|
@ -0,0 +1,20 @@
|
|||
# Generated by Django 2.2.17 on 2020-12-20 17:20
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("elections", "0002_auto_20201220_1735"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="election",
|
||||
name="restricted",
|
||||
field=models.BooleanField(
|
||||
default=True, verbose_name="restreint le vote à une liste de personnes"
|
||||
),
|
||||
),
|
||||
]
|
25
elections/migrations/0004_auto_20201220_1847.py
Normal file
25
elections/migrations/0004_auto_20201220_1847.py
Normal file
|
@ -0,0 +1,25 @@
|
|||
# Generated by Django 2.2.17 on 2020-12-20 17:47
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("elections", "0003_election_restricted"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="user",
|
||||
name="election",
|
||||
field=models.ForeignKey(
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="registered_voters",
|
||||
to="elections.Election",
|
||||
),
|
||||
),
|
||||
]
|
|
@ -35,7 +35,7 @@ class RestrictAccessMixin(SelectElectionMixin):
|
|||
return qs.none()
|
||||
|
||||
|
||||
class OpenElectionOnly(RestrictAccessMixin):
|
||||
class OpenElectionOnlyMixin(RestrictAccessMixin):
|
||||
"""N'autorise la vue que lorsque l'élection est ouverte"""
|
||||
|
||||
def get_filters(self):
|
||||
|
|
|
@ -1,16 +1,8 @@
|
|||
from django.conf import settings
|
||||
from django.contrib.auth.models import AbstractUser
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
# #############################################################################
|
||||
# Modification of the base User Model
|
||||
# #############################################################################
|
||||
|
||||
|
||||
class User(AbstractUser):
|
||||
pass
|
||||
|
||||
|
||||
# #############################################################################
|
||||
# Models regarding an election
|
||||
# #############################################################################
|
||||
|
@ -24,8 +16,16 @@ class Election(models.Model):
|
|||
start_date = models.DateTimeField(_("date et heure de début"))
|
||||
end_date = models.DateTimeField(_("date et heure de fin"))
|
||||
|
||||
restricted = models.BooleanField(
|
||||
_("restreint le vote à une liste de personnes"), default=True
|
||||
)
|
||||
|
||||
created_by = models.ForeignKey(
|
||||
User, on_delete=models.SET_NULL, blank=True, null=True
|
||||
settings.AUTH_USER_MODEL,
|
||||
related_name="elections_created",
|
||||
on_delete=models.SET_NULL,
|
||||
blank=True,
|
||||
null=True,
|
||||
)
|
||||
|
||||
results_public = models.BooleanField(_("résultats publics"), default=False)
|
||||
|
@ -58,7 +58,7 @@ class Option(models.Model):
|
|||
)
|
||||
text = models.TextField(_("texte"), blank=False)
|
||||
voters = models.ManyToManyField(
|
||||
User,
|
||||
settings.AUTH_USER_MODEL,
|
||||
related_name="votes",
|
||||
)
|
||||
# For now, we store the amount of votes received after the election is tallied
|
||||
|
@ -66,3 +66,26 @@ class Option(models.Model):
|
|||
|
||||
class Meta:
|
||||
ordering = ["id"]
|
||||
|
||||
|
||||
# #############################################################################
|
||||
# Modification of the base User Model
|
||||
# #############################################################################
|
||||
|
||||
|
||||
class User(AbstractUser):
|
||||
election = models.ForeignKey(
|
||||
Election,
|
||||
related_name="registered_voters",
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
def can_vote(self, election):
|
||||
# Si c'est un·e utilisateur·ice CAS, iel peut voter dans les élections
|
||||
# ouvertes à tou·te·s
|
||||
if self.election is None:
|
||||
return not election.restricted
|
||||
# Pour les élections restreintes, il faut y être associé
|
||||
return election.restricted and (self.election == election)
|
||||
|
|
|
@ -2,7 +2,7 @@ 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.http import Http404, HttpResponseRedirect
|
||||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
from django.utils.text import slugify
|
||||
|
@ -16,7 +16,7 @@ from django.views.generic import (
|
|||
)
|
||||
|
||||
from .forms import ElectionForm, OptionForm, OptionFormSet, QuestionForm
|
||||
from .mixins import CreatorOnlyEditMixin, CreatorOnlyMixin, OpenElectionOnly
|
||||
from .mixins import CreatorOnlyEditMixin, CreatorOnlyMixin, OpenElectionOnlyMixin
|
||||
from .models import Election, Option, Question
|
||||
|
||||
# TODO: access control *everywhere*
|
||||
|
@ -268,14 +268,6 @@ class ElectionView(DetailView):
|
|||
def get_context_data(self, **kwargs):
|
||||
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 (
|
||||
|
@ -286,7 +278,7 @@ class ElectionView(DetailView):
|
|||
)
|
||||
|
||||
|
||||
class VoteView(OpenElectionOnly, DetailView):
|
||||
class VoteView(OpenElectionOnlyMixin, DetailView):
|
||||
model = Question
|
||||
template_name = "elections/vote.html"
|
||||
|
||||
|
@ -302,6 +294,14 @@ class VoteView(OpenElectionOnly, DetailView):
|
|||
|
||||
return reverse("election.vote", args=[q_next])
|
||||
|
||||
def get_object(self):
|
||||
question = super().get_object()
|
||||
# Seulement les utilisateur·ice·s ayant le droit de voter dans l'élection
|
||||
# peuvent voir la page
|
||||
if not self.request.user.can_vote(question.election):
|
||||
raise Http404
|
||||
return question
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
self.object = self.get_object()
|
||||
vote_form = OptionFormSet(instance=self.object)
|
||||
|
|
Loading…
Reference in a new issue