diff --git a/election/models.py b/election/models.py index b2659424..d95f0a1e 100644 --- a/election/models.py +++ b/election/models.py @@ -1,9 +1,7 @@ from django.db import models from django.utils.translation import ugettext_lazy as _ from django.utils import timezone -from django.conf import settings -from datetime import timedelta from core.models import User, Group @@ -13,16 +11,26 @@ class Election(models.Model): """ title = models.CharField(_('title'), max_length=255) description = models.TextField(_('description'), null=True, blank=True) - start_candidature = models.DateTimeField(_('start candidature'), blank=False) + start_candidature = models.DateTimeField( + _('start candidature'), blank=False) end_candidature = models.DateTimeField(_('end candidature'), blank=False) start_date = models.DateTimeField(_('start date'), blank=False) end_date = models.DateTimeField(_('end date'), blank=False) - edit_groups = models.ManyToManyField(Group, related_name="editable_elections", verbose_name=_("edit groups"), blank=True) - view_groups = models.ManyToManyField(Group, related_name="viewable_elections", verbose_name=_("view groups"), blank=True) - vote_groups = models.ManyToManyField(Group, related_name="votable_elections", verbose_name=_("vote groups"), blank=True) - candidature_groups = models.ManyToManyField(Group, related_name="candidate_elections", verbose_name=_("candidature groups"), blank=True) - voters = models.ManyToManyField(User, verbose_name=('voters'), related_name='voted_elections') + edit_groups = models.ManyToManyField( + Group, related_name="editable_elections", + verbose_name=_("edit groups"), blank=True) + view_groups = models.ManyToManyField( + Group, related_name="viewable_elections", + verbose_name=_("view groups"), blank=True) + vote_groups = models.ManyToManyField( + Group, related_name="votable_elections", + verbose_name=_("vote groups"), blank=True) + candidature_groups = models.ManyToManyField( + Group, related_name="candidate_elections", + verbose_name=_("candidature groups"), blank=True) + voters = models.ManyToManyField(User, verbose_name=( + 'voters'), related_name='voted_elections') def __str__(self): return self.title @@ -39,7 +47,8 @@ class Election(models.Model): @property def is_candidature_active(self): now = timezone.now() - return bool(now <= self.end_candidature and now >= self.start_candidature) + return bool(now <= self.end_candidature and + now >= self.start_candidature) @property def is_vote_editable(self): @@ -77,7 +86,8 @@ class Role(models.Model): """ This class allows to create a new role avaliable for a candidature """ - election = models.ForeignKey(Election, related_name='roles', verbose_name=_("election")) + election = models.ForeignKey( + Election, related_name='roles', verbose_name=_("election")) title = models.CharField(_('title'), max_length=255) description = models.TextField(_('description'), null=True, blank=True) max_choice = models.IntegerField(_('max choice'), default=1) @@ -88,11 +98,13 @@ class Role(models.Model): non_blank = 0 for candidature in self.candidatures.all(): cand_results = {} - cand_results['vote'] = self.votes.filter(candidature=candidature).count() + cand_results['vote'] = self.votes.filter( + candidature=candidature).count() if total_vote == 0: cand_results['percent'] = 0 else: - cand_results['percent'] = cand_results['vote'] * 100 / total_vote + cand_results['percent'] = cand_results[ + 'vote'] * 100 / total_vote non_blank += cand_results['vote'] results[candidature.user.username] = cand_results results['total vote'] = total_vote @@ -100,7 +112,8 @@ class Role(models.Model): results['blank vote'] = {'vote': 0, 'percent': 0} else: results['blank vote'] = {'vote': total_vote - non_blank, - 'percent': (total_vote - non_blank) * 100 / total_vote} + 'percent': (total_vote - + non_blank) * 100 / total_vote} return results @property @@ -116,7 +129,8 @@ class ElectionList(models.Model): To allow per list vote """ title = models.CharField(_('title'), max_length=255) - election = models.ForeignKey(Election, related_name='election_lists', verbose_name=_("election")) + election = models.ForeignKey( + Election, related_name='election_lists', verbose_name=_("election")) def __str__(self): return self.title @@ -126,10 +140,14 @@ class Candidature(models.Model): """ This class is a component of responsability """ - role = models.ForeignKey(Role, related_name='candidatures', verbose_name=_("role")) - user = models.ForeignKey(User, verbose_name=_('user'), related_name='candidates', blank=True) + role = models.ForeignKey( + Role, related_name='candidatures', verbose_name=_("role")) + user = models.ForeignKey(User, verbose_name=_( + 'user'), related_name='candidates', blank=True) program = models.TextField(_('description'), null=True, blank=True) - election_list = models.ForeignKey(ElectionList, related_name='candidatures', verbose_name=_('election list')) + election_list = models.ForeignKey( + ElectionList, related_name='candidatures', + verbose_name=_('election list')) def can_be_edited_by(self, user): return (user == self.user) or user.can_edit(self.role.election) @@ -142,8 +160,10 @@ class Vote(models.Model): """ This class allows to vote for candidates """ - role = models.ForeignKey(Role, related_name='votes', verbose_name=_("role")) - candidature = models.ManyToManyField(Candidature, related_name='votes', verbose_name=_("candidature")) + role = models.ForeignKey( + Role, related_name='votes', verbose_name=_("role")) + candidature = models.ManyToManyField( + Candidature, related_name='votes', verbose_name=_("candidature")) def __str__(self): - return "Vote" \ No newline at end of file + return "Vote" diff --git a/election/tests.py b/election/tests.py index a2bd3f2f..91bc350f 100644 --- a/election/tests.py +++ b/election/tests.py @@ -1,11 +1,10 @@ -from django.test import Client, TestCase +from django.test import TestCase from django.core.urlresolvers import reverse from django.contrib.auth.models import Group from django.core.management import call_command from django.conf import settings -from datetime import date, datetime -from core.models import User, Group +from core.models import User from election.models import Election @@ -15,8 +14,10 @@ class MainElection(TestCase): self.election = Election.objects.all().first() self.public_group = Group.objects.get(id=settings.SITH_GROUP_PUBLIC_ID) - self.subscriber_group = Group.objects.get(name=settings.SITH_MAIN_MEMBERS_GROUP) - self.ae_board_group = Group.objects.get(name=settings.SITH_MAIN_BOARD_GROUP) + self.subscriber_group = Group.objects.get( + name=settings.SITH_MAIN_MEMBERS_GROUP) + self.ae_board_group = Group.objects.get( + name=settings.SITH_MAIN_BOARD_GROUP) self.sli = User.objects.get(username='sli') self.subscriber = User.objects.get(username='subscriber') self.public = User.objects.get(username='public') @@ -29,9 +30,9 @@ class ElectionDetailTest(MainElection): self.election.save() self.client.login(username=self.public.username, password='plop') response_get = self.client.get(reverse('election:detail', - args=str(self.election.id))) + args=str(self.election.id))) response_post = self.client.get(reverse('election:detail', - args=str(self.election.id))) + args=str(self.election.id))) self.assertTrue(response_get.status_code == 403) self.assertTrue(response_post.status_code == 403) self.election.view_groups.remove(self.subscriber_group) @@ -41,9 +42,9 @@ class ElectionDetailTest(MainElection): def test_permisson_granted(self): self.client.login(username=self.public.username, password='plop') response_get = self.client.get(reverse('election:detail', - args=str(self.election.id))) + args=str(self.election.id))) response_post = self.client.post(reverse('election:detail', - args=str(self.election.id))) + args=str(self.election.id))) self.assertFalse(response_get.status_code == 403) self.assertFalse(response_post.status_code == 403) self.assertTrue('La roue tourne' in str(response_get.content)) @@ -53,8 +54,8 @@ class ElectionUpdateView(MainElection): def test_permission_denied(self): self.client.login(username=self.subscriber.username, password='plop') response_get = self.client.get(reverse('election:update', - args=str(self.election.id))) + args=str(self.election.id))) response_post = self.client.post(reverse('election:update', - args=str(self.election.id))) + args=str(self.election.id))) self.assertTrue(response_get.status_code == 403) self.assertTrue(response_post.status_code == 403) diff --git a/election/urls.py b/election/urls.py index 8140cb49..fe94dab6 100644 --- a/election/urls.py +++ b/election/urls.py @@ -5,14 +5,24 @@ from election.views import * urlpatterns = [ url(r'^$', ElectionsListView.as_view(), name='list'), url(r'^add$', ElectionCreateView.as_view(), name='create'), - url(r'^(?P[0-9]+)/edit$', ElectionUpdateView.as_view(), name='update'), - url(r'^(?P[0-9]+)/list/add$', ElectionListCreateView.as_view(), name='create_list'), - url(r'^(?P[0-9]+)/role/create$', RoleCreateView.as_view(), name='create_role'), - url(r'^(?P[0-9]+)/role/edit$', RoleUpdateView.as_view(), name='update_role'), - url(r'^(?P[0-9]+)/role/delete$', RoleDeleteView.as_view(), name='delete_role'), - url(r'^(?P[0-9]+)/candidate/add$', CandidatureCreateView.as_view(), name='candidate'), - url(r'^(?P[0-9]+)/candidate/edit$', CandidatureUpdateView.as_view(), name='update_candidate'), - url(r'^(?P[0-9]+)/candidate/delete$', CandidatureDeleteView.as_view(), name='delete_candidate'), - url(r'^(?P[0-9]+)/vote$', VoteFormView.as_view(), name='vote'), - url(r'^(?P[0-9]+)/detail$', ElectionDetailView.as_view(), name='detail'), + url(r'^(?P[0-9]+)/edit$', + ElectionUpdateView.as_view(), name='update'), + url(r'^(?P[0-9]+)/list/add$', + ElectionListCreateView.as_view(), name='create_list'), + url(r'^(?P[0-9]+)/role/create$', + RoleCreateView.as_view(), name='create_role'), + url(r'^(?P[0-9]+)/role/edit$', + RoleUpdateView.as_view(), name='update_role'), + url(r'^(?P[0-9]+)/role/delete$', + RoleDeleteView.as_view(), name='delete_role'), + url(r'^(?P[0-9]+)/candidate/add$', + CandidatureCreateView.as_view(), name='candidate'), + url(r'^(?P[0-9]+)/candidate/edit$', + CandidatureUpdateView.as_view(), name='update_candidate'), + url(r'^(?P[0-9]+)/candidate/delete$', + CandidatureDeleteView.as_view(), name='delete_candidate'), + url(r'^(?P[0-9]+)/vote$', + VoteFormView.as_view(), name='vote'), + url(r'^(?P[0-9]+)/detail$', + ElectionDetailView.as_view(), name='detail'), ] diff --git a/election/views.py b/election/views.py index 2c4a8821..47230338 100644 --- a/election/views.py +++ b/election/views.py @@ -1,19 +1,16 @@ -from django.shortcuts import redirect, get_object_or_404 -from django.views.generic import ListView, DetailView, RedirectView -from django.views.generic.edit import UpdateView, CreateView, DeleteView, FormView -from django.core.urlresolvers import reverse_lazy, reverse +from django.shortcuts import get_object_or_404 +from django.views.generic import ListView, DetailView +from django.views.generic.edit import UpdateView, CreateView +from django.views.generic.edit import DeleteView, FormView +from django.core.urlresolvers import reverse_lazy from django.utils.translation import ugettext_lazy as _ -from django.forms.models import modelform_factory -from django.core.exceptions import PermissionDenied, ObjectDoesNotExist, ImproperlyConfigured -from django.db import DataError, transaction +from django.core.exceptions import PermissionDenied +from django.db import transaction from django.forms import CheckboxSelectMultiple -from django.utils import timezone -from django.conf import settings from django import forms -from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin +from core.views import CanViewMixin, CanEditMixin, CanCreateMixin from django.db.models.query import QuerySet -from django.views.generic.edit import FormMixin from core.views.forms import SelectDateTime from election.models import Election, Role, Candidature, ElectionList, Vote @@ -27,12 +24,16 @@ class LimitedCheckboxField(forms.ModelMultipleChoiceField): Used to replace ModelMultipleChoiceField but with automatic backend verification """ - def __init__(self, queryset, max_choice, required=True, widget=None, label=None, - initial=None, help_text='', *args, **kwargs): + + def __init__(self, queryset, max_choice, required=True, widget=None, + label=None, initial=None, help_text='', *args, **kwargs): self.max_choice = max_choice widget = forms.CheckboxSelectMultiple() - super(LimitedCheckboxField, self).__init__(queryset, None, required, widget, label, - initial, help_text, *args, **kwargs) + super(LimitedCheckboxField, self).__init__(queryset, + None, required, + widget, label, + initial, help_text, + *args, **kwargs) def clean(self, value): qs = super(LimitedCheckboxField, self).clean(value) @@ -41,7 +42,8 @@ class LimitedCheckboxField(forms.ModelMultipleChoiceField): def validate(self, qs): if qs.count() > self.max_choice: - raise forms.ValidationError(_("You have selected too much candidates."), code='invalid') + raise forms.ValidationError( + _("You have selected too much candidates."), code='invalid') # Forms @@ -56,15 +58,18 @@ class CandidateForm(forms.ModelForm): 'program': forms.Textarea } - user = AutoCompleteSelectField('users', label=_('User to candidate'), help_text=None, required=True) + user = AutoCompleteSelectField('users', label=_( + 'User to candidate'), help_text=None, required=True) def __init__(self, *args, **kwargs): election_id = kwargs.pop('election_id', None) can_edit = kwargs.pop('can_edit', False) super(CandidateForm, self).__init__(*args, **kwargs) if election_id: - self.fields['role'].queryset = Role.objects.filter(election__id=election_id).all() - self.fields['election_list'].queryset = ElectionList.objects.filter(election__id=election_id).all() + self.fields['role'].queryset = Role.objects.filter( + election__id=election_id).all() + self.fields['election_list'].queryset \ + = ElectionList.objects.filter(election__id=election_id).all() if not can_edit: self.fields['user'].widget = forms.HiddenInput() @@ -76,10 +81,13 @@ class VoteForm(forms.Form): for role in election.roles.all(): cand = role.candidatures if role.max_choice > 1: - self.fields[role.title] = LimitedCheckboxField(cand, role.max_choice, required=False) + self.fields[role.title] = LimitedCheckboxField( + cand, role.max_choice, required=False) else: - self.fields[role.title] = forms.ModelChoiceField(cand, required=False, - widget=forms.RadioSelect(), empty_label=_("Blank vote")) + self.fields[role.title] \ + = forms.ModelChoiceField(cand, required=False, + widget=forms.RadioSelect(), + empty_label=_("Blank vote")) class RoleForm(forms.ModelForm): @@ -92,33 +100,40 @@ class RoleForm(forms.ModelForm): election_id = kwargs.pop('election_id', None) super(RoleForm, self).__init__(*args, **kwargs) if election_id: - self.fields['election'].queryset = Election.objects.filter(id=election_id).all() + self.fields['election'].queryset = Election.objects.filter( + id=election_id).all() def clean(self): cleaned_data = super(RoleForm, self).clean() title = cleaned_data.get('title') election = cleaned_data.get('election') if Role.objects.filter(title=title, election=election).exists(): - raise forms.ValidationError(_("This role already exists for this election"), code='invalid') + raise forms.ValidationError( + _("This role already exists for this election"), + code='invalid') class ElectionListForm(forms.ModelForm): class Meta: model = ElectionList - fields = ('title','election') + fields = ('title', 'election') def __init__(self, *args, **kwargs): election_id = kwargs.pop('election_id', None) super(ElectionListForm, self).__init__(*args, **kwargs) if election_id: - self.fields['election'].queryset = Election.objects.filter(id=election_id).all() + self.fields['election'].queryset = Election.objects.filter( + id=election_id).all() class ElectionForm(forms.ModelForm): class Meta: model = Election - fields = ['title', 'description', 'start_candidature', 'end_candidature', 'start_date', 'end_date', - 'edit_groups', 'view_groups', 'vote_groups', 'candidature_groups'] + fields = ['title', 'description', + 'start_candidature', 'end_candidature', + 'start_date', 'end_date', + 'edit_groups', 'view_groups', + 'vote_groups', 'candidature_groups'] widgets = { 'edit_groups': CheckboxSelectMultiple, 'view_groups': CheckboxSelectMultiple, @@ -127,10 +142,18 @@ class ElectionForm(forms.ModelForm): 'candidature_groups': CheckboxSelectMultiple } - start_date = forms.DateTimeField(['%Y-%m-%d %H:%M:%S'], label=_("Start date"), widget=SelectDateTime, required=True) - end_date = forms.DateTimeField(['%Y-%m-%d %H:%M:%S'], label=_("End date"), widget=SelectDateTime, required=True) - start_candidature = forms.DateTimeField(['%Y-%m-%d %H:%M:%S'], label=_("Start candidature"), widget=SelectDateTime, required=True) - end_candidature = forms.DateTimeField(['%Y-%m-%d %H:%M:%S'], label=_("End candidature"), widget=SelectDateTime, required=True) + start_date = forms.DateTimeField( + ['%Y-%m-%d %H:%M:%S'], label=_("Start date"), + widget=SelectDateTime, required=True) + end_date = forms.DateTimeField( + ['%Y-%m-%d %H:%M:%S'], label=_("End date"), + widget=SelectDateTime, required=True) + start_candidature = forms.DateTimeField( + ['%Y-%m-%d %H:%M:%S'], label=_("Start candidature"), + widget=SelectDateTime, required=True) + end_candidature = forms.DateTimeField( + ['%Y-%m-%d %H:%M:%S'], label=_("End candidature"), + widget=SelectDateTime, required=True) # Display elections @@ -179,7 +202,8 @@ class VoteFormView(CanCreateMixin, FormView): # If we have a multiple choice field if isinstance(election_data[role_title], QuerySet): if election_data[role_title].count() > 0: - vote = Vote(role=election_data[role_title].first().role) + vote = Vote(role=election_data[ + role_title].first().role) vote.save() for el in election_data[role_title]: vote.candidature.add(el) @@ -209,7 +233,8 @@ class VoteFormView(CanCreateMixin, FormView): return res def get_success_url(self, **kwargs): - return reverse_lazy('election:detail', kwargs={'election_id': self.election.id}) + return reverse_lazy('election:detail', + kwargs={'election_id': self.election.id}) def get_context_data(self, **kwargs): """ Add additionnal data to the template """ @@ -232,7 +257,8 @@ class CandidatureCreateView(CanCreateMixin, CreateView): def dispatch(self, request, *arg, **kwargs): self.election = get_object_or_404(Election, pk=kwargs['election_id']) - return super(CandidatureCreateView, self).dispatch(request, *arg, **kwargs) + return super(CandidatureCreateView, + self).dispatch(request, *arg, **kwargs) def get_initial(self): init = {} @@ -252,7 +278,8 @@ class CandidatureCreateView(CanCreateMixin, CreateView): """ obj = form.instance obj.election = Election.objects.get(id=self.election.id) - if(obj.election.can_candidate(obj.user)) and (obj.user == self.request.user or self.can_edit): + if(obj.election.can_candidate(obj.user)) and \ + (obj.user == self.request.user or self.can_edit): return super(CreateView, self).form_valid(form) raise PermissionDenied @@ -262,7 +289,8 @@ class CandidatureCreateView(CanCreateMixin, CreateView): return kwargs def get_success_url(self, **kwargs): - return reverse_lazy('election:detail', kwargs={'election_id': self.election.id}) + return reverse_lazy('election:detail', + kwargs={'election_id': self.election.id}) class ElectionCreateView(CanCreateMixin, CreateView): @@ -273,16 +301,19 @@ class ElectionCreateView(CanCreateMixin, CreateView): def dispatch(self, request, *args, **kwargs): if not request.user.is_subscribed: raise PermissionDenied - return super(ElectionCreateView, self).dispatch(request, *args, **kwargs) + return super(ElectionCreateView, + self).dispatch(request, *args, **kwargs) def form_valid(self, form): """ - Allow every users that had passed the dispatch to create an election + Allow every users that had passed the dispatch + to create an election """ return super(CreateView, self).form_valid(form) def get_success_url(self, **kwargs): - return reverse_lazy('election:detail', kwargs={'election_id': self.object.id}) + return reverse_lazy('election:detail', + kwargs={'election_id': self.object.id}) class RoleCreateView(CanCreateMixin, CreateView): @@ -318,7 +349,8 @@ class RoleCreateView(CanCreateMixin, CreateView): return kwargs def get_success_url(self, **kwargs): - return reverse_lazy('election:detail', kwargs={'election_id': self.object.election.id}) + return reverse_lazy('election:detail', + kwargs={'election_id': self.object.election.id}) class ElectionListCreateView(CanCreateMixin, CreateView): @@ -330,7 +362,8 @@ class ElectionListCreateView(CanCreateMixin, CreateView): self.election = get_object_or_404(Election, pk=kwargs['election_id']) if not self.election.is_vote_editable: raise PermissionDenied - return super(ElectionListCreateView, self).dispatch(request, *arg, **kwargs) + return super(ElectionListCreateView, + self).dispatch(request, *arg, **kwargs) def get_initial(self): init = {} @@ -357,7 +390,8 @@ class ElectionListCreateView(CanCreateMixin, CreateView): raise PermissionDenied def get_success_url(self, **kwargs): - return reverse_lazy('election:detail', kwargs={'election_id': self.object.election.id}) + return reverse_lazy('election:detail', + kwargs={'election_id': self.object.election.id}) # Update view @@ -371,21 +405,30 @@ class ElectionUpdateView(CanEditMixin, UpdateView): def get_initial(self): init = {} try: - init['start_date'] = self.object.start_date.strftime('%Y-%m-%d %H:%M:%S') - except:pass + init['start_date'] = self.object.start_date.strftime( + '%Y-%m-%d %H:%M:%S') + except Exception: + pass try: - init['end_date'] = self.object.end_date.strftime('%Y-%m-%d %H:%M:%S') - except:pass + init['end_date'] = self.object.end_date.strftime( + '%Y-%m-%d %H:%M:%S') + except Exception: + pass try: - init['start_candidature'] = self.object.start_candidature.strftime('%Y-%m-%d %H:%M:%S') - except:pass + init['start_candidature'] = self.object.start_candidature.strftime( + '%Y-%m-%d %H:%M:%S') + except Exception: + pass try: - init['end_candidature'] = self.object.end_candidature.strftime('%Y-%m-%d %H:%M:%S') - except:pass + init['end_candidature'] = self.object.end_candidature.strftime( + '%Y-%m-%d %H:%M:%S') + except Exception: + pass return init def get_success_url(self, **kwargs): - return reverse_lazy('election:detail', kwargs={'election_id': self.object.id}) + return reverse_lazy('election:detail', + kwargs={'election_id': self.object.id}) class CandidatureUpdateView(CanEditMixin, UpdateView): @@ -398,7 +441,8 @@ class CandidatureUpdateView(CanEditMixin, UpdateView): self.object = self.get_object() if not self.object.role.election.is_vote_editable: raise PermissionDenied - return super(CandidatureUpdateView, self).dispatch(request, *arg, **kwargs) + return super(CandidatureUpdateView, + self).dispatch(request, *arg, **kwargs) def remove_fields(self): self.form.fields.pop('role', None) @@ -411,7 +455,8 @@ class CandidatureUpdateView(CanEditMixin, UpdateView): def post(self, request, *args, **kwargs): self.form = self.get_form() self.remove_fields() - if request.user.is_authenticated() and request.user.can_edit(self.object) and self.form.is_valid(): + if request.user.is_authenticated() and \ + request.user.can_edit(self.object) and self.form.is_valid(): return super(CandidatureUpdateView, self).form_valid(self.form) return self.form_invalid(self.form) @@ -421,7 +466,9 @@ class CandidatureUpdateView(CanEditMixin, UpdateView): return kwargs def get_success_url(self, **kwargs): - return reverse_lazy('election:detail', kwargs={'election_id': self.object.role.election.id}) + return reverse_lazy('election:detail', + kwargs={'election_id': + self.object.role.election.id}) class RoleUpdateView(CanEditMixin, UpdateView): @@ -449,7 +496,8 @@ class RoleUpdateView(CanEditMixin, UpdateView): self.object = self.get_object() self.form = self.get_form() self.remove_fields() - if request.user.is_authenticated() and request.user.can_edit(self.object) and self.form.is_valid(): + if request.user.is_authenticated() and \ + request.user.can_edit(self.object) and self.form.is_valid(): return super(RoleUpdateView, self).form_valid(self.form) return self.form_invalid(self.form) @@ -459,7 +507,8 @@ class RoleUpdateView(CanEditMixin, UpdateView): return kwargs def get_success_url(self, **kwargs): - return reverse_lazy('election:detail', kwargs={'election_id': self.object.election.id}) + return reverse_lazy('election:detail', + kwargs={'election_id': self.object.election.id}) # Delete Views @@ -472,12 +521,15 @@ class CandidatureDeleteView(CanEditMixin, DeleteView): def dispatch(self, request, *arg, **kwargs): self.object = self.get_object() self.election = self.object.role.election - if not self.election.can_candidate or not self.election.is_vote_editable: + if not self.election.can_candidate \ + or not self.election.is_vote_editable: raise PermissionDenied - return super(CandidatureDeleteView, self).dispatch(request, *arg, **kwargs) + return super(CandidatureDeleteView, + self).dispatch(request, *arg, **kwargs) def get_success_url(self, **kwargs): - return reverse_lazy('election:detail', kwargs={'election_id': self.election.id}) + return reverse_lazy('election:detail', + kwargs={'election_id': self.election.id}) class RoleDeleteView(CanEditMixin, DeleteView): @@ -493,4 +545,5 @@ class RoleDeleteView(CanEditMixin, DeleteView): return super(RoleDeleteView, self).dispatch(request, *arg, **kwargs) def get_success_url(self, **kwargs): - return reverse_lazy('election:detail', kwargs={'election_id': self.election.id}) + return reverse_lazy('election:detail', + kwargs={'election_id': self.election.id})