mirror of
https://github.com/ae-utbm/sith.git
synced 2024-11-22 06:03:20 +00:00
Full CRUD for elections
This commit is contained in:
parent
4f62863599
commit
c07f49305b
@ -41,6 +41,10 @@ class Election(models.Model):
|
|||||||
now = timezone.now()
|
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):
|
||||||
|
return bool(timezone.now() <= self.end_candidature)
|
||||||
|
|
||||||
def can_candidate(self, user):
|
def can_candidate(self, user):
|
||||||
for group in self.candidature_groups.all():
|
for group in self.candidature_groups.all():
|
||||||
if user.is_in_group(group):
|
if user.is_in_group(group):
|
||||||
@ -95,6 +99,10 @@ class Role(models.Model):
|
|||||||
'percent': (total_vote - non_blank) * 100 / total_vote}
|
'percent': (total_vote - non_blank) * 100 / total_vote}
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
@property
|
||||||
|
def edit_groups(self):
|
||||||
|
return self.election.edit_groups
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return ("%s : %s") % (self.election.title, self.title)
|
return ("%s : %s") % (self.election.title, self.title)
|
||||||
|
|
||||||
@ -119,6 +127,9 @@ class Candidature(models.Model):
|
|||||||
program = models.TextField(_('description'), null=True, 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)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s : %s" % (self.role.title, self.user.username)
|
return "%s : %s" % (self.role.title, self.user.username)
|
||||||
|
|
||||||
|
15
election/templates/election/create_template.jinja
Normal file
15
election/templates/election/create_template.jinja
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{% extends "core/base.jinja" %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
{% trans %}Create{% endtrans %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h2>{% trans %}Create{% endtrans %}
|
||||||
|
<section class="election__add-candidature">
|
||||||
|
<form action="" method="post">{{form.as_p()}}
|
||||||
|
<p><input type="submit" value="{% trans %}Save{% endtrans %}" /></p>
|
||||||
|
{% csrf_token %}
|
||||||
|
</form>
|
||||||
|
</section>
|
||||||
|
{% endblock content %}
|
12
election/templates/election/delete_template.jinja
Normal file
12
election/templates/election/delete_template.jinja
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{% extends "core/base.jinja" %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
{% trans %}Delete{% endtrans %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<form action="" method="post">{% csrf_token %}
|
||||||
|
<p>{% trans %}Are you sure you want to delete {% endtrans %}"{{ object }}"?</p>
|
||||||
|
<input type="submit" value="Confirm" />
|
||||||
|
</form>
|
||||||
|
{% endblock content %}
|
@ -273,6 +273,10 @@ th {
|
|||||||
<tr class="role__title">
|
<tr class="role__title">
|
||||||
<td colspan="{{election_lists.count() + 1}}">
|
<td colspan="{{election_lists.count() + 1}}">
|
||||||
<span>{{role.title}}</span>
|
<span>{{role.title}}</span>
|
||||||
|
{% if user.can_edit(role) and election.is_vote_editable -%}
|
||||||
|
<a href="{{url('election:update_role', role_id=role.id)}}">{% trans %}Edit{% endtrans %}</a>
|
||||||
|
<a href="{{url('election:delete_role', role_id=role.id)}}">{% trans %}Delete{% endtrans %}</a>
|
||||||
|
{%- endif -%}
|
||||||
{%- if role.max_choice > 1 and not election.has_voted(user) and election.can_vote(user) %}
|
{%- if role.max_choice > 1 and not election.has_voted(user) and election.can_vote(user) %}
|
||||||
<strong class="role__multiple-choices-label">{% trans %}You may choose up to{% endtrans %} {{ role.max_choice }} {% trans %}people.{% endtrans %}</strong>
|
<strong class="role__multiple-choices-label">{% trans %}You may choose up to{% endtrans %} {{ role.max_choice }} {% trans %}people.{% endtrans %}</strong>
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
@ -313,6 +317,14 @@ th {
|
|||||||
<figcaption class="candidate__details">
|
<figcaption class="candidate__details">
|
||||||
<cite class="candidate__full-name">{{ candidature.user.first_name }} <em class="candidate__nick-name">{{candidature.user.nick_name or ''}} </em>{{ candidature.user.last_name }}</cite>
|
<cite class="candidate__full-name">{{ candidature.user.first_name }} <em class="candidate__nick-name">{{candidature.user.nick_name or ''}} </em>{{ candidature.user.last_name }}</cite>
|
||||||
<q class="candidate__program">{{ candidature.program or '' }}</q>
|
<q class="candidate__program">{{ candidature.program or '' }}</q>
|
||||||
|
{%- if user.can_edit(candidature) -%}
|
||||||
|
{% if election.is_vote_editable %}
|
||||||
|
<a href="{{url('election:update_candidate', candidature_id=candidature.id)}}">{% trans %}Edit{% endtrans %}</a>
|
||||||
|
{% endif %}
|
||||||
|
{% if election.can_candidate -%}
|
||||||
|
<a href="{{url('election:delete_candidate', candidature_id=candidature.id)}}">{% trans %}Delete{% endtrans %}</a>
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endif -%}
|
||||||
</figcaption>
|
</figcaption>
|
||||||
</figure>
|
</figure>
|
||||||
{%- if election.can_vote(user) %}
|
{%- if election.can_vote(user) %}
|
||||||
|
15
election/templates/election/update_template.jinja
Normal file
15
election/templates/election/update_template.jinja
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{% extends "core/base.jinja" %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
{% trans %}Edit{% endtrans %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h2>{% trans %}Edit{% endtrans %}
|
||||||
|
<section class="election__add-candidature">
|
||||||
|
<form action="" method="post">{{form.as_p()}}
|
||||||
|
<p><input type="submit" value="{% trans %}Save{% endtrans %}" /></p>
|
||||||
|
{% csrf_token %}
|
||||||
|
</form>
|
||||||
|
</section>
|
||||||
|
{% endblock content %}
|
@ -8,7 +8,11 @@ urlpatterns = [
|
|||||||
url(r'^(?P<election_id>[0-9]+)/edit$', ElectionUpdateView.as_view(), name='update'),
|
url(r'^(?P<election_id>[0-9]+)/edit$', ElectionUpdateView.as_view(), name='update'),
|
||||||
url(r'^(?P<election_id>[0-9]+)/list/add$', ElectionListCreateView.as_view(), name='create_list'),
|
url(r'^(?P<election_id>[0-9]+)/list/add$', ElectionListCreateView.as_view(), name='create_list'),
|
||||||
url(r'^(?P<election_id>[0-9]+)/role/create$', RoleCreateView.as_view(), name='create_role'),
|
url(r'^(?P<election_id>[0-9]+)/role/create$', RoleCreateView.as_view(), name='create_role'),
|
||||||
|
url(r'^(?P<role_id>[0-9]+)/role/edit$', RoleUpdateView.as_view(), name='update_role'),
|
||||||
|
url(r'^(?P<role_id>[0-9]+)/role/delete$', RoleDeleteView.as_view(), name='delete_role'),
|
||||||
url(r'^(?P<election_id>[0-9]+)/candidate/add$', CandidatureCreateView.as_view(), name='candidate'),
|
url(r'^(?P<election_id>[0-9]+)/candidate/add$', CandidatureCreateView.as_view(), name='candidate'),
|
||||||
|
url(r'^(?P<candidature_id>[0-9]+)/candidate/edit$', CandidatureUpdateView.as_view(), name='update_candidate'),
|
||||||
|
url(r'^(?P<candidature_id>[0-9]+)/candidate/delete$', CandidatureDeleteView.as_view(), name='delete_candidate'),
|
||||||
url(r'^(?P<election_id>[0-9]+)/vote$', VoteFormView.as_view(), name='vote'),
|
url(r'^(?P<election_id>[0-9]+)/vote$', VoteFormView.as_view(), name='vote'),
|
||||||
url(r'^(?P<election_id>[0-9]+)/detail$', ElectionDetailView.as_view(), name='detail'),
|
url(r'^(?P<election_id>[0-9]+)/detail$', ElectionDetailView.as_view(), name='detail'),
|
||||||
]
|
]
|
||||||
|
@ -265,7 +265,7 @@ class CandidatureCreateView(CanCreateMixin, CreateView):
|
|||||||
class ElectionCreateView(CanCreateMixin, CreateView):
|
class ElectionCreateView(CanCreateMixin, CreateView):
|
||||||
model = Election
|
model = Election
|
||||||
form_class = ElectionForm
|
form_class = ElectionForm
|
||||||
template_name = 'core/page_prop.jinja'
|
template_name = 'election/create_template.jinja'
|
||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
if not request.user.is_subscribed():
|
if not request.user.is_subscribed():
|
||||||
@ -285,11 +285,11 @@ class ElectionCreateView(CanCreateMixin, CreateView):
|
|||||||
class RoleCreateView(CanCreateMixin, CreateView):
|
class RoleCreateView(CanCreateMixin, CreateView):
|
||||||
model = Role
|
model = Role
|
||||||
form_class = RoleForm
|
form_class = RoleForm
|
||||||
template_name = 'core/page_prop.jinja'
|
template_name = 'election/create_template.jinja'
|
||||||
|
|
||||||
def dispatch(self, request, *arg, **kwargs):
|
def dispatch(self, request, *arg, **kwargs):
|
||||||
self.election = get_object_or_404(Election, pk=kwargs['election_id'])
|
self.election = get_object_or_404(Election, pk=kwargs['election_id'])
|
||||||
if self.election.is_vote_active or self.election.is_vote_finished:
|
if self.election.is_vote_editable:
|
||||||
raise PermissionDenied
|
raise PermissionDenied
|
||||||
return super(RoleCreateView, self).dispatch(request, *arg, **kwargs)
|
return super(RoleCreateView, self).dispatch(request, *arg, **kwargs)
|
||||||
|
|
||||||
@ -321,11 +321,11 @@ class RoleCreateView(CanCreateMixin, CreateView):
|
|||||||
class ElectionListCreateView(CanCreateMixin, CreateView):
|
class ElectionListCreateView(CanCreateMixin, CreateView):
|
||||||
model = ElectionList
|
model = ElectionList
|
||||||
form_class = ElectionListForm
|
form_class = ElectionListForm
|
||||||
template_name = 'core/page_prop.jinja'
|
template_name = 'election/create_template.jinja'
|
||||||
|
|
||||||
def dispatch(self, request, *arg, **kwargs):
|
def dispatch(self, request, *arg, **kwargs):
|
||||||
self.election = get_object_or_404(Election, pk=kwargs['election_id'])
|
self.election = get_object_or_404(Election, pk=kwargs['election_id'])
|
||||||
if self.election.is_vote_finished:
|
if not self.election.is_vote_editable:
|
||||||
raise PermissionDenied
|
raise PermissionDenied
|
||||||
return super(ElectionListCreateView, self).dispatch(request, *arg, **kwargs)
|
return super(ElectionListCreateView, self).dispatch(request, *arg, **kwargs)
|
||||||
|
|
||||||
@ -362,6 +362,116 @@ class ElectionListCreateView(CanCreateMixin, CreateView):
|
|||||||
class ElectionUpdateView(CanEditMixin, UpdateView):
|
class ElectionUpdateView(CanEditMixin, UpdateView):
|
||||||
model = Election
|
model = Election
|
||||||
form_class = ElectionForm
|
form_class = ElectionForm
|
||||||
template_name = 'core/page_prop.jinja'
|
template_name = 'election/update_template.jinja'
|
||||||
pk_url_kwarg = 'election_id'
|
pk_url_kwarg = 'election_id'
|
||||||
|
|
||||||
|
def get_success_url(self, **kwargs):
|
||||||
|
return reverse_lazy('election:detail', kwargs={'election_id': self.object.id})
|
||||||
|
|
||||||
|
|
||||||
|
class CandidatureUpdateView(CanEditMixin, UpdateView):
|
||||||
|
model = Candidature
|
||||||
|
form_class = CandidateForm
|
||||||
|
template_name = 'election/update_template.jinja'
|
||||||
|
pk_url_kwarg = 'candidature_id'
|
||||||
|
|
||||||
|
def dispatch(self, request, *arg, **kwargs):
|
||||||
|
self.object = self.get_object()
|
||||||
|
if not self.object.role.election.is_vote_editable:
|
||||||
|
raise PermissionDenied
|
||||||
|
return super(CandidatureUpdateView, self).dispatch(request, *arg, **kwargs)
|
||||||
|
|
||||||
|
def remove_fields(self):
|
||||||
|
self.form.fields.pop('role', None)
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
self.form = self.get_form()
|
||||||
|
self.remove_fields()
|
||||||
|
return self.render_to_response(self.get_context_data(form=self.form))
|
||||||
|
|
||||||
|
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():
|
||||||
|
return super(CandidatureUpdateView, self).form_valid(self.form)
|
||||||
|
return self.form_invalid(self.form)
|
||||||
|
|
||||||
|
def get_form_kwargs(self):
|
||||||
|
kwargs = super(CandidatureUpdateView, self).get_form_kwargs()
|
||||||
|
kwargs['election_id'] = self.object.role.election.id
|
||||||
|
return kwargs
|
||||||
|
|
||||||
|
def get_success_url(self, **kwargs):
|
||||||
|
return reverse_lazy('election:detail', kwargs={'election_id': self.object.role.election.id})
|
||||||
|
|
||||||
|
|
||||||
|
class RoleUpdateView(CanEditMixin, UpdateView):
|
||||||
|
model = Role
|
||||||
|
form_class = RoleForm
|
||||||
|
template_name = 'election/update_template.jinja'
|
||||||
|
pk_url_kwarg = 'role_id'
|
||||||
|
|
||||||
|
def dispatch(self, request, *arg, **kwargs):
|
||||||
|
self.object = self.get_object()
|
||||||
|
if not self.object.election.is_vote_editable:
|
||||||
|
raise PermissionDenied
|
||||||
|
return super(RoleUpdateView, self).dispatch(request, *arg, **kwargs)
|
||||||
|
|
||||||
|
def remove_fields(self):
|
||||||
|
self.form.fields.pop('election', None)
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
self.object = self.get_object()
|
||||||
|
self.form = self.get_form()
|
||||||
|
self.remove_fields()
|
||||||
|
return self.render_to_response(self.get_context_data(form=self.form))
|
||||||
|
|
||||||
|
def post(self, request, *args, **kwargs):
|
||||||
|
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():
|
||||||
|
return super(RoleUpdateView, self).form_valid(self.form)
|
||||||
|
return self.form_invalid(self.form)
|
||||||
|
|
||||||
|
def get_form_kwargs(self):
|
||||||
|
kwargs = super(RoleUpdateView, self).get_form_kwargs()
|
||||||
|
kwargs['election_id'] = self.object.election.id
|
||||||
|
return kwargs
|
||||||
|
|
||||||
|
def get_success_url(self, **kwargs):
|
||||||
|
return reverse_lazy('election:detail', kwargs={'election_id': self.object.election.id})
|
||||||
|
|
||||||
|
# Delete Views
|
||||||
|
|
||||||
|
|
||||||
|
class CandidatureDeleteView(CanEditMixin, DeleteView):
|
||||||
|
model = Candidature
|
||||||
|
template_name = 'election/delete_template.jinja'
|
||||||
|
pk_url_kwarg = 'candidature_id'
|
||||||
|
|
||||||
|
def dispatch(self, request, *arg, **kwargs):
|
||||||
|
self.object = self.get_object()
|
||||||
|
self.election = self.object.role.election
|
||||||
|
if not self.election.can_candidate:
|
||||||
|
raise PermissionDenied
|
||||||
|
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})
|
||||||
|
|
||||||
|
|
||||||
|
class RoleDeleteView(CanEditMixin, DeleteView):
|
||||||
|
model = Role
|
||||||
|
template_name = 'election/delete_template.jinja'
|
||||||
|
pk_url_kwarg = 'role_id'
|
||||||
|
|
||||||
|
def dispatch(self, request, *arg, **kwargs):
|
||||||
|
self.object = self.get_object()
|
||||||
|
self.election = self.object.election
|
||||||
|
if not self.election.is_vote_editable:
|
||||||
|
raise PermissionDenied
|
||||||
|
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})
|
||||||
|
Loading…
Reference in New Issue
Block a user