diff --git a/core/widgets.py b/core/widgets.py
deleted file mode 100644
index e1d6cd47..00000000
--- a/core/widgets.py
+++ /dev/null
@@ -1,94 +0,0 @@
-from django import forms
-from django.utils.safestring import mark_safe
-
-class ChoiceWithOtherRenderer(forms.RadioSelect.renderer):
- """RadioFieldRenderer that renders its last choice with a placeholder."""
- def __init__(self, *args, **kwargs):
- super(ChoiceWithOtherRenderer, self).__init__(*args, **kwargs)
- self.choices, self.other = self.choices[:-1], self.choices[-1]
-
- def __iter__(self):
- for input in super(ChoiceWithOtherRenderer, self).__iter__():
- yield input
- id = '%s_%s' % (self.attrs['id'], self.other[0]) if 'id' in self.attrs else ''
- label_for = ' for="%s"' % id if id else ''
- checked = '' if not self.other[0] == self.value else 'checked="true" '
- yield ' %%s' % (
- label_for, id, self.other[0], self.name, checked, self.other[1])
-
-class ChoiceWithOtherWidget(forms.MultiWidget):
- """MultiWidget for use with ChoiceWithOtherField."""
- def __init__(self, choices):
- widgets = [
- forms.RadioSelect(choices=choices, renderer=ChoiceWithOtherRenderer),
- forms.TextInput
- ]
- super(ChoiceWithOtherWidget, self).__init__(widgets)
-
- def decompress(self, value):
- if not value:
- return [None, None]
- return value
-
- def format_output(self, rendered_widgets):
- """Format the output by substituting the "other" choice into the first widget."""
- return rendered_widgets[0] % rendered_widgets[1]
-
-class ChoiceWithOtherField(forms.MultiValueField):
- """
- ChoiceField with an option for a user-submitted "other" value.
-
- The last item in the choices array passed to __init__ is expected to be a choice for "other". This field's
- cleaned data is a tuple consisting of the choice the user made, and the "other" field typed in if the choice
- made was the last one.
-
- >>> class AgeForm(forms.Form):
- ... age = ChoiceWithOtherField(choices=[
- ... (0, '15-29'),
- ... (1, '30-44'),
- ... (2, '45-60'),
- ... (3, 'Other, please specify:')
- ... ])
- ...
- >>> # rendered as a RadioSelect choice field whose last choice has a text input
- ... print AgeForm()['age']
-
-
-
-
-
-
- >>> form = AgeForm({'age_0': 2})
- >>> form.is_valid()
- True
- >>> form.cleaned_data
- {'age': (u'2', u'')}
- >>> form = AgeForm({'age_0': 3, 'age_1': 'I am 10 years old'})
- >>> form.is_valid()
- True
- >>> form.cleaned_data
- {'age': (u'3', u'I am 10 years old')}
- >>> form = AgeForm({'age_0': 1, 'age_1': 'This is bogus text which is ignored since I didn\\'t pick "other"'})
- >>> form.is_valid()
- True
- >>> form.cleaned_data
- {'age': (u'1', u'')}
- """
- def __init__(self, *args, **kwargs):
- fields = [
- forms.ChoiceField(widget=forms.RadioSelect(renderer=ChoiceWithOtherRenderer), *args, **kwargs),
- forms.CharField(required=False)
- ]
- widget = ChoiceWithOtherWidget(choices=kwargs['choices'])
- kwargs.pop('choices')
- self._was_required = kwargs.pop('required', True)
- kwargs['required'] = False
- super(ChoiceWithOtherField, self).__init__(widget=widget, fields=fields, *args, **kwargs)
-
- def compress(self, value):
- if self._was_required and not value or value[0] in (None, ''):
- raise forms.ValidationError(self.error_messages['required'])
- if not value:
- return [None, u'']
- return (value[0], value[1] if value[0] == self.fields[0].choices[-1][0] else u'')
\ No newline at end of file
diff --git a/election/models.py b/election/models.py
index 979c3beb..8e3fbc92 100644
--- a/election/models.py
+++ b/election/models.py
@@ -80,6 +80,9 @@ class Candidature(models.Model):
program = models.TextField(_('description'), null=True, blank=True)
election_list = models.ForeignKey(ElectionList, related_name='candidature', verbose_name=_('election_list'))
+ def __str__(self):
+ return "%s : %s" % (self.role.title, self.user.username)
+
class Vote(models.Model):
"""
diff --git a/election/urls.py b/election/urls.py
index 380fa1db..59ad8a42 100644
--- a/election/urls.py
+++ b/election/urls.py
@@ -8,5 +8,6 @@ urlpatterns = [
url(r'^list/create$', ElectionListCreateView.as_view(), name='create_list'),
url(r'^role/create$', RoleCreateView.as_view(), name='create_role'),
url(r'^(?P[0-9]+)/candidate$', CandidatureCreateView.as_view(), name='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 d253e58d..e11955a0 100644
--- a/election/views.py
+++ b/election/views.py
@@ -11,8 +11,8 @@ from django.conf import settings
from django import forms
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin
+from django.views.generic.edit import FormMixin
from core.views.forms import SelectDateTime
-from core.widgets import ChoiceWithOtherField
from election.models import Election, Role, Candidature, ElectionList
from ajax_select.fields import AutoCompleteSelectField
@@ -31,6 +31,25 @@ class CandidateForm(forms.Form):
self.fields['role'] = forms.ModelChoiceField(Role.objects.filter(election__id=election_id))
self.fields['election_list'] = forms.ModelChoiceField(ElectionList.objects.filter(election__id=election_id))
+
+class VoteForm(forms.Form):
+ def __init__(self, role_id, *args, **kwargs):
+ super(VoteForm, self).__init__(*args, **kwargs)
+ self.max_choice = Role.objects.get(id=role_id).max_choice
+ cand = Candidature.objects.filter(role__id=role_id)
+ if self.max_choice > 1:
+ self.fields['candidature'] = forms.ModelMultipleChoiceField(cand, required=False,
+ widget=forms.CheckboxSelectMultiple())
+ else:
+ self.fields['candidature'] = forms.ModelChoiceField(cand, required=False,
+ widget=forms.RadioSelect(), empty_label=_("Blank vote"))
+
+ def clean_candidature(self):
+ data = self.cleaned_data['candidature']
+ if self.max_choice > 1 and len(data) > self.max_choice:
+ raise forms.ValidationError(_("You have selected too much candidate"))
+ return data
+
# Display elections
@@ -110,6 +129,43 @@ class CandidatureCreateView(CanCreateMixin, FormView):
return reverse_lazy('election:detail', kwargs={'election_id': self.election_id})
+class VoteFormView(CanCreateMixin, FormView):
+ """
+ Alows users to vote
+ """
+ form_class = VoteForm
+ template_name = 'core/page_prop.jinja'
+
+ def dispatch(self, request, *arg, **kwargs):
+ self.election_id = kwargs['election_id']
+ return super(VoteFormView, self).dispatch(request, *arg, **kwargs)
+
+ def vote(self, data):
+ pass
+
+ def get_form_kwargs(self):
+ kwargs = super(VoteFormView, self).get_form_kwargs()
+ kwargs['role_id'] = self.election_id
+ return kwargs
+
+ def form_valid(self, form):
+ """
+ Verify that the user is part in a vote group
+ """
+ data = form.clean()
+ res = super(FormView, self).form_valid(form)
+ if self.request.user.is_root:
+ self.vote(data)
+ return res
+ for grp in data['role'].election.vote_groups.all():
+ if self.request.user.is_in_group(grp):
+ self.vote(data)
+ return res
+ return res
+
+ def get_success_url(self, **kwargs):
+ return reverse_lazy('election:detail', kwargs={'election_id': self.election_id})
+
# Create views