mirror of
https://github.com/ae-utbm/sith.git
synced 2024-11-21 21:53:30 +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()
|
||||
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):
|
||||
for group in self.candidature_groups.all():
|
||||
if user.is_in_group(group):
|
||||
@ -95,6 +99,10 @@ class Role(models.Model):
|
||||
'percent': (total_vote - non_blank) * 100 / total_vote}
|
||||
return results
|
||||
|
||||
@property
|
||||
def edit_groups(self):
|
||||
return self.election.edit_groups
|
||||
|
||||
def __str__(self):
|
||||
return ("%s : %s") % (self.election.title, self.title)
|
||||
|
||||
@ -119,6 +127,9 @@ class Candidature(models.Model):
|
||||
program = models.TextField(_('description'), null=True, blank=True)
|
||||
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):
|
||||
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">
|
||||
<td colspan="{{election_lists.count() + 1}}">
|
||||
<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) %}
|
||||
<strong class="role__multiple-choices-label">{% trans %}You may choose up to{% endtrans %} {{ role.max_choice }} {% trans %}people.{% endtrans %}</strong>
|
||||
{%- endif %}
|
||||
@ -313,6 +317,14 @@ th {
|
||||
<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>
|
||||
<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>
|
||||
</figure>
|
||||
{%- 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]+)/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<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<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]+)/detail$', ElectionDetailView.as_view(), name='detail'),
|
||||
]
|
||||
|
@ -265,7 +265,7 @@ class CandidatureCreateView(CanCreateMixin, CreateView):
|
||||
class ElectionCreateView(CanCreateMixin, CreateView):
|
||||
model = Election
|
||||
form_class = ElectionForm
|
||||
template_name = 'core/page_prop.jinja'
|
||||
template_name = 'election/create_template.jinja'
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
if not request.user.is_subscribed():
|
||||
@ -285,11 +285,11 @@ class ElectionCreateView(CanCreateMixin, CreateView):
|
||||
class RoleCreateView(CanCreateMixin, CreateView):
|
||||
model = Role
|
||||
form_class = RoleForm
|
||||
template_name = 'core/page_prop.jinja'
|
||||
template_name = 'election/create_template.jinja'
|
||||
|
||||
def dispatch(self, request, *arg, **kwargs):
|
||||
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
|
||||
return super(RoleCreateView, self).dispatch(request, *arg, **kwargs)
|
||||
|
||||
@ -321,11 +321,11 @@ class RoleCreateView(CanCreateMixin, CreateView):
|
||||
class ElectionListCreateView(CanCreateMixin, CreateView):
|
||||
model = ElectionList
|
||||
form_class = ElectionListForm
|
||||
template_name = 'core/page_prop.jinja'
|
||||
template_name = 'election/create_template.jinja'
|
||||
|
||||
def dispatch(self, request, *arg, **kwargs):
|
||||
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
|
||||
return super(ElectionListCreateView, self).dispatch(request, *arg, **kwargs)
|
||||
|
||||
@ -362,6 +362,116 @@ class ElectionListCreateView(CanCreateMixin, CreateView):
|
||||
class ElectionUpdateView(CanEditMixin, UpdateView):
|
||||
model = Election
|
||||
form_class = ElectionForm
|
||||
template_name = 'core/page_prop.jinja'
|
||||
template_name = 'election/update_template.jinja'
|
||||
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