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:
|
class Meta:
|
||||||
model = Election
|
model = Election
|
||||||
fields = ["name", "description", "start_date", "end_date"]
|
fields = ["name", "description", "restricted", "start_date", "end_date"]
|
||||||
|
|
||||||
|
|
||||||
class QuestionForm(forms.ModelForm):
|
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()
|
return qs.none()
|
||||||
|
|
||||||
|
|
||||||
class OpenElectionOnly(RestrictAccessMixin):
|
class OpenElectionOnlyMixin(RestrictAccessMixin):
|
||||||
"""N'autorise la vue que lorsque l'élection est ouverte"""
|
"""N'autorise la vue que lorsque l'élection est ouverte"""
|
||||||
|
|
||||||
def get_filters(self):
|
def get_filters(self):
|
||||||
|
|
|
@ -1,16 +1,8 @@
|
||||||
|
from django.conf import settings
|
||||||
from django.contrib.auth.models import AbstractUser
|
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 _
|
||||||
|
|
||||||
# #############################################################################
|
|
||||||
# Modification of the base User Model
|
|
||||||
# #############################################################################
|
|
||||||
|
|
||||||
|
|
||||||
class User(AbstractUser):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
# #############################################################################
|
# #############################################################################
|
||||||
# Models regarding an election
|
# Models regarding an election
|
||||||
# #############################################################################
|
# #############################################################################
|
||||||
|
@ -24,8 +16,16 @@ class Election(models.Model):
|
||||||
start_date = models.DateTimeField(_("date et heure de début"))
|
start_date = models.DateTimeField(_("date et heure de début"))
|
||||||
end_date = models.DateTimeField(_("date et heure de fin"))
|
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(
|
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)
|
results_public = models.BooleanField(_("résultats publics"), default=False)
|
||||||
|
@ -58,7 +58,7 @@ class Option(models.Model):
|
||||||
)
|
)
|
||||||
text = models.TextField(_("texte"), blank=False)
|
text = models.TextField(_("texte"), blank=False)
|
||||||
voters = models.ManyToManyField(
|
voters = models.ManyToManyField(
|
||||||
User,
|
settings.AUTH_USER_MODEL,
|
||||||
related_name="votes",
|
related_name="votes",
|
||||||
)
|
)
|
||||||
# For now, we store the amount of votes received after the election is tallied
|
# For now, we store the amount of votes received after the election is tallied
|
||||||
|
@ -66,3 +66,26 @@ class Option(models.Model):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ["id"]
|
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.contrib.messages.views import SuccessMessageMixin
|
||||||
|
|
||||||
# from django.db.models import Count, Prefetch
|
# 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.urls import reverse
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.text import slugify
|
from django.utils.text import slugify
|
||||||
|
@ -16,7 +16,7 @@ from django.views.generic import (
|
||||||
)
|
)
|
||||||
|
|
||||||
from .forms import ElectionForm, OptionForm, OptionFormSet, QuestionForm
|
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
|
from .models import Election, Option, Question
|
||||||
|
|
||||||
# TODO: access control *everywhere*
|
# TODO: access control *everywhere*
|
||||||
|
@ -268,14 +268,6 @@ class ElectionView(DetailView):
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
kwargs.update({"current_time": timezone.now()})
|
kwargs.update({"current_time": timezone.now()})
|
||||||
return super().get_context_data(**kwargs)
|
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):
|
def get_queryset(self):
|
||||||
return (
|
return (
|
||||||
|
@ -286,7 +278,7 @@ class ElectionView(DetailView):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class VoteView(OpenElectionOnly, DetailView):
|
class VoteView(OpenElectionOnlyMixin, DetailView):
|
||||||
model = Question
|
model = Question
|
||||||
template_name = "elections/vote.html"
|
template_name = "elections/vote.html"
|
||||||
|
|
||||||
|
@ -302,6 +294,14 @@ class VoteView(OpenElectionOnly, DetailView):
|
||||||
|
|
||||||
return reverse("election.vote", args=[q_next])
|
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):
|
def get(self, request, *args, **kwargs):
|
||||||
self.object = self.get_object()
|
self.object = self.get_object()
|
||||||
vote_form = OptionFormSet(instance=self.object)
|
vote_form = OptionFormSet(instance=self.object)
|
||||||
|
|
Loading…
Add table
Reference in a new issue