use the new poll-api in assignments

This commit is contained in:
Oskar Hahn 2012-02-19 19:27:00 +01:00
parent 5aaa1a53fa
commit 70f1cb8b3e
8 changed files with 159 additions and 179 deletions

View File

@ -496,12 +496,7 @@ class ApplicationOption(BaseOption):
def __getattr__(self, name):
if name in ['yes', 'no', 'contained']:
try:
value = self.get_votes().get(value=name).weight
if value == -1:
return _('majority')
if value == -2:
return _('undocumented')
return value
return self.get_votes().get(value=name)
except Vote.DoesNotExist:
pass
raise AttributeError(name)
@ -517,6 +512,7 @@ class ApplicationPoll(BasePoll, CountInvalid, CountVotesCast):
return self.application
def set_options(self):
#TODO: maybe it is possible with .create() to call this without poll=self
self.get_option_class()(poll=self).save()
def append_pollform_fields(self, fields):

View File

@ -79,9 +79,9 @@
<img src="/static/images/icons/voting-yes.png" title="{% trans 'Yes' %}"> {{ option.yes }}<br>
<img src="/static/images/icons/voting-no.png" title="{% trans 'No' %}"> {{ option.no }}<br>
<img src="/static/images/icons/voting-abstention.png" title="{% trans 'Abstention' %}"> {{ option.contained }}<br>
<img src="/static/images/icons/voting-invalid.png" title="{% trans 'Invalid' %}"> {{ poll.votesinvalid }}<br>
<img src="/static/images/icons/voting-invalid.png" title="{% trans 'Invalid' %}"> {{ poll.print_votesinvalid }}<br>
<div style="border-top: 1px solid; padding-top: 5px; margin: 5px 0; width: 10em;">
<img src="/static/images/icons/voting-total.png" title="{% trans 'Votes cast' %}"> {{ poll.votescast }}
<img src="/static/images/icons/voting-total.png" title="{% trans 'Votes cast' %}"> {{ poll.poll_votescast }}
</div>
{% endwith %}
{% if perms.application.can_manage_application %}

View File

@ -17,6 +17,7 @@ from participant.models import Profile
from projector.models import Slide
from projector.api import register_slidemodel
from poll.models import BasePoll, CountInvalid, CountVotesCast, BaseOption
class Assignment(models.Model, Slide):
@ -73,7 +74,7 @@ class Assignment(models.Model, Slide):
@property
def candidates(self):
return Profile.objects.filter(option__poll__assignment=self).order_by('user__first_name').distinct()
return self.profile.get_query_set()
def set_elected(self, profile, value=True):
if profile in self.candidates:
@ -88,33 +89,9 @@ class Assignment(models.Model, Slide):
return False
def gen_poll(self):
from poll.models import Poll
poll = Poll()
candidates = list(self.profile.all())
for elected in self.elected.all():
try:
candidates.remove(elected)
except ValueError:
pass
# Option A: candidates <= available posts -> yes/no/abstention
if len(candidates) <= self.posts - self.elected.count():
poll.optiondecision = True
else:
poll.optiondecision = False
# Option B: candidates == 1 -> yes/no/abstention
#if self.profile.count() == 1:
# poll.optiondecision = True
#else:
# poll.optiondecision = False
poll.assignment = self
poll.description = self.polldescription
poll = AssignmentPoll(assignment=self)
poll.save()
for candidate in candidates:
poll.add_option(candidate)
poll.set_options([{'candidate': profile} for profile in self.profile.all()])
return poll
def slide(self):
@ -146,3 +123,23 @@ class Assignment(models.Model, Slide):
)
register_slidemodel(Assignment)
class AssignmentOption(BaseOption):
candidate = models.ForeignKey(Profile)
def __unicode__(self):
return unicode(self.candidate)
class AssignmentPoll(BasePoll, CountInvalid, CountVotesCast):
option_class = AssignmentOption
assignment = models.ForeignKey(Assignment, related_name='poll_set')
def get_assignment(self):
return self.assignment
def append_pollform_fields(self, fields):
CountInvalid.append_pollform_fields(self, fields)
CountVotesCast.append_pollform_fields(self, fields)

View File

@ -12,37 +12,32 @@
<p><b>{% trans "Short description" %}:</b> {{ poll.description }}</p>
<i>-1 := {% trans 'majority' %}, -2 := {% trans 'undocumented' %}</i>
<form action="" method="post">{% csrf_token %}
<table class="table" style="width:auto;">
<table>
<tr>
<th>{%trans "Option" %}</th>
{% if poll.optiondecision %}
<th>{%trans "Yes" %}</th>
<th>{%trans "No" %}</th>
<th>{%trans "Abstention" %}</th>
{% else %}
<th>{%trans "Votes" %}</th>
{% endif %}
<th>Option</th>
{% for value in poll.get_vote_values %}
<th>{{ value }}</th>
{% endfor %}
</tr>
{% for option in options %}
<tr class="{% cycle 'odd' '' %}">
<td>{{ option }}</td>
{% if poll.optiondecision %}
<td>{{ option.form.yes.errors }}{{ option.form.yes }}</td>
<td>{{ option.form.no.errors }}{{ option.form.no }}</td>
<td>{{ option.form.undesided.errors }}{{ option.form.undesided }}</td>
{% else %}
<td>{{ option.form.yes.errors }}{{ option.form.yes }}</td>
{% endif %}
{% for form in forms %}
<tr>
<td>{{ form.option }}</td>
{% for value in form %}
<td>
{{ value.errors }}
{{ value }}
</td>
{% endfor %}
</tr>
{% endfor %}
<tr class="total">
<td>{% trans "Invalid votes" %}</td>
<td {% if poll.optiondecision %}colspan="3"{% endif %}>{{ form.invalid.errors }}{{ form.invalid }}</td>
</tr>
<tr class="total">
<td style="white-space: nowrap;"><b>{% trans "Votes cast" %}</b></td>
<td {% if poll.optiondecision %}colspan="3"{% endif %}>{{ form.votescast.errors }}{{ form.votescast }}</td>
</tr>
<tr class="total">
<td>{% trans "Invalid votes" %}</td>
<td>{{ pollform.votesinvalid.errors }}{{ pollform.votesinvalid }}</td>
</tr>
<tr class="total">
<td>{% trans "Votes cast" %}</td>
<td>{{ pollform.votescast.errors }}{{ pollform.votescast }}</td>
</tr>
</table>
<p>

View File

@ -119,46 +119,46 @@
<p><br></p>
<h3>{% trans "Election results" %}</h3>
{% if assignment.poll_set.all.count > 0 %}
{% if polls %}
<table id="election_table" style="width: auto;">
<tr>
<th></th>
{% with ballotnumber=assignment.poll_set.all.count %}
<th colspan="{{ ballotnumber|add:'1' }}" style="text-align: center;">
{% trans "ballot" %}</th>
{% endwith %}
<th></th>
{% with ballotnumber=polls.count %}
<th colspan="{{ ballotnumber|add:'1' }}" style="text-align: center;">
{% trans "ballot" %}</th>
{% endwith %}
</tr>
<tr>
<th>{% trans "Candidates" %}</th>
{% for poll in assignment.poll_set.all %}
{% if poll.published and not perms.assignment.can_manage_assignment or perms.assignment.can_manage_assignment %}
<th style="vertical-align: top; white-space:nowrap;">{% if perms.assignment.can_manage_assignment %}<a href="{% url assignment_poll_view poll.id %}">{% endif %}
{{ forloop.counter }}. {% trans 'ballot' %}
{% if perms.assignment.can_manage_assignment %}
</a>
{% if poll.published %}
<a href={% url assignment_poll_notpublish poll.id %}><img
src="/static/images/icons/user-online.png"
title="{% trans 'Unpublish results' %}"></a>
{% else %}
<a href={% url assignment_poll_publish poll.id %}><img
src="/static/images/icons/user-offline.png"
title="{% trans 'Publish results' %}"></a>
<th>{% trans "Candidates" %}</th>
{% for poll in polls %}
{# if poll.published and not perms.assignment.can_manage_assignment or perms.assignment.can_manage_assignment #}
<th style="vertical-align: top; white-space:nowrap;">{% if perms.assignment.can_manage_assignment %}<a href="{% url assignment_poll_view poll.id %}">{% endif %}
{{ forloop.counter }}. {% trans 'ballot' %}
{% if perms.assignment.can_manage_assignment %}
</a>
{% if poll.published %}
<a href={% url assignment_poll_notpublish poll.id %}><img
src="/static/images/icons/user-online.png"
title="{% trans 'Unpublish results' %}"></a>
{% else %}
<a href={% url assignment_poll_publish poll.id %}><img
src="/static/images/icons/user-offline.png"
title="{% trans 'Publish results' %}"></a>
{% endif %}
<a href="{% url assignment_poll_delete poll.id %}"><img src="/static/images/icons/edit-delete.png" title="{% trans 'Delete Poll' %}"></a>
{% endif %}
</th>
{# endif #}
{% endfor %}
{% if assignment.profile.count > 0 and perms.assignment.can_manage_assignment and assignment.status == "vot" %}
<th>
<a href='{% url assignment_gen_poll assignment.id %}'>
<span class="button">
<span class="icon poll">{%trans 'New ballot' %}</span>
</span>
</a>
</th>
{% endif %}
<a href="{% url assignment_poll_delete poll.id %}"><img src="/static/images/icons/edit-delete.png" title="{% trans 'Delete Poll' %}"></a>
{% endif %}
</th>
{% endif %}
{% endfor %}
{% if assignment.profile.count > 0 and perms.assignment.can_manage_assignment and assignment.status == "vot" %}
<th>
<a href='{% url assignment_gen_poll assignment.id %}'>
<span class="button">
<span class="icon poll">{%trans 'New ballot' %}</span>
</span>
</a>
</th>
{% endif %}
</tr>
{% for vote in votes %}
@ -167,20 +167,21 @@
{% with vote|first as candidate %}
{% if candidate.1 %}
{% if perms.assignment.can_manage_assignment %}
<a class="election_link elected" href='{% url assignment_user_not_elected assignment.id candidate.0.id %}'></a>
<a class="election_link elected" href='{% url assignment_user_not_elected assignment.id candidate.0.id %}'></a>
{% else %}
<a class="elected"><img src="/static/images/icons/games-highscores.png" title="{% trans 'Candidate is elected' %}"></a>
<a class="elected"><img src="/static/images/icons/games-highscores.png" title="{% trans 'Candidate is elected' %}"></a>
{% endif %}
{% else %}
{% if perms.assignment.can_manage_assignment %}
<a class="election_link" href='{% url assignment_user_elected assignment.id candidate.0.id %}'></a>
<a class="election_link" href='{% url assignment_user_elected assignment.id candidate.0.id %}'></a>
{% endif %}
{% endif %}
{{ candidate.0 }}
{% endwith %}
</td>
{% for v in vote|last %}
<td style="white-space:nowrap;">{% if v %}
<td style="white-space:nowrap;">
{% if v %}
{% if v|length == 3 %}
<img src="/static/images/icons/voting-yes.png" title="{% trans 'Yes' %}"> {% if v.0 %}{{ v.0 }}{% else %}&empty;{% endif %}<br>
<img src="/static/images/icons/voting-no.png" title="{% trans 'No' %}"> {% if v.1 %}{{ v.1 }}{% else %}&empty;{% endif %}<br>
@ -189,7 +190,9 @@
{% if v != "-" %}<img src="/static/images/icons/voting-yes.png" title="{% trans 'Yes' %}">{% endif %}
{{ v }}
{% endif %}
{% else %}&empty;{% endif %}
{% else %}
&empty;
{% endif %}
</td>
{% endfor %}
{% if assignment.profile.exists and perms.assignment.can_manage_assignment and assignment.status == "vot" %}
@ -199,9 +202,9 @@
{% endfor %}
<tr>
<td>{%trans 'Invalid votes' %}</td>
{% for p in polls %}
{% if p.published and not perms.assignment.can_manage_assignment or perms.assignment.can_manage_assignment %}
<td style="white-space:nowrap;"><img src="/static/images/icons/voting-invalid.png" title="{% trans 'Invalid' %}"> {{ p.votesinvalidf }}</td>
{% for poll in polls %}
{% if poll.published and not perms.assignment.can_manage_assignment or perms.assignment.can_manage_assignment %}
<td style="white-space:nowrap;"><img src="/static/images/icons/voting-invalid.png" title="{% trans 'Invalid' %}"> {{ poll.print_votesinvalid }}</td>
{% endif %}
{% endfor %}
{% if assignment.profile.exists and perms.assignment.can_manage_assignment and assignment.status == "vot" %}
@ -210,9 +213,9 @@
</tr>
<tr class="total">
<td><b>{%trans 'Votes cast' %}</b></td>
{% for p in polls %}
{% if p.published and not perms.assignment.can_manage_assignment or perms.assignment.can_manage_assignment %}
<td style="white-space:nowrap;"><img src="/static/images/icons/voting-total.png" title="{% trans 'Votes cast' %}"> <b>{{ p.votescastf }}</b></td>
{% for poll in polls %}
{% if poll.published and not perms.assignment.can_manage_assignment or perms.assignment.can_manage_assignment %}
<td style="white-space:nowrap;"><img src="/static/images/icons/voting-total.png" title="{% trans 'Votes cast' %}"> <b>{{ poll.print_votescast }}</b></td>
{% endif %}
{% endfor %}
{% if assignment.profile.exists and perms.assignment.can_manage_assignment and assignment.status == "vot" %}

View File

@ -12,6 +12,8 @@
from django.conf.urls.defaults import *
from assignment.views import ViewPoll #, ActivatePoll
urlpatterns = patterns('assignment.views',
url(r'^assignment/$', 'get_overview', \
name='assignment_overview'),
@ -55,8 +57,10 @@ urlpatterns = patterns('assignment.views',
url(r'^assignment/(?P<assignment_id>\d+)/gen_poll$', 'gen_poll', \
name='assignment_gen_poll'),
url(r'^assignment/poll/(?P<poll_id>\d+)$', 'poll_view', \
name='assignment_poll_view'),
url(r'^assignment/poll/(?P<poll_id>\d+)$',
ViewPoll.as_view(),
name='assignment_poll_view'
),
url(r'^assignment/poll/(?P<poll_id>\d+)/del$', 'delete_poll', \
name='assignment_poll_delete'),

View File

@ -16,13 +16,14 @@ from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.utils.translation import ugettext as _
from openslides.agenda.models import Item
#from poll.models import Poll, Option
#from poll.forms import OptionResultForm, PollForm
from assignment.models import Assignment
from assignment.forms import AssignmentForm, AssignmentRunForm
from utils.utils import template, permission_required, gen_confirm_form, del_confirm_form, ajax_request
from utils.pdf import print_assignment, print_assignment_poll
from poll.views import PollFormView
from assignment.models import Assignment, AssignmentPoll, AssignmentOption
from assignment.forms import AssignmentForm, AssignmentRunForm
from participant.models import Profile
@ -69,26 +70,26 @@ def view(request, assignment_id=None):
votes = []
for candidate in assignment.candidates:
tmplist = [[candidate, assignment.is_elected(candidate)], []]
#TODO: only show published polls
for poll in assignment.poll_set.all():
if (poll.published and not request.user.has_perm('assignment.can_manage_assignment')) or request.user.has_perm('assignment.can_manage_assignment'):
if candidate in poll.options_values:
option = Option.objects.filter(poll=poll).filter(user=candidate)[0]
if poll.optiondecision:
tmplist[1].append([option.yes, option.no, option.undesided])
else:
tmplist[1].append(option.yes)
else:
tmplist[1].append("-")
#if (poll.published and not request.user.has_perm('assignment.can_manage_assignment')) or request.user.has_perm('assignment.can_manage_assignment'):
# exisitiert der Spieler in der poll
if poll.get_options().filter(candidate=candidate).exists():
option = AssignmentOption.objects.filter(poll=poll).get(candidate=candidate)
tmplist[1].append(option.get_votes()[0])
else:
tmplist[1].append("-")
votes.append(tmplist)
polls = []
for poll in assignment.poll_set.filter(assignment=assignment):
polls.append(poll)
polls = assignment.poll_set.all()
return {'assignment': assignment,
'form': form,
'votes': votes,
'polls': polls }
return {
'assignment': assignment,
'form': form,
'votes': votes,
'polls': polls,
}
@permission_required('assignment.can_manage_assignment')
@ -193,56 +194,26 @@ def set_active(request, assignment_id):
@permission_required('assignment.can_manage_assignment')
def gen_poll(request, assignment_id):
try:
poll = Assignment.objects.get(pk=assignment_id).gen_poll()
messages.success(request, _("New ballot was successfully created.") )
except Assignment.DoesNotExist:
pass
poll = Assignment.objects.get(pk=assignment_id).gen_poll()
messages.success(request, _("New ballot was successfully created.") )
return redirect(reverse('assignment_poll_view', args=[poll.id]))
@permission_required('assignment.can_manage_assignment')
@template('assignment/poll_view.html')
def poll_view(request, poll_id):
poll = Poll.objects.get(pk=poll_id)
ballotnumber = poll.ballot
options = poll.options.order_by('user__user__first_name')
assignment = poll.assignment
if request.user.has_perm('assignment.can_manage_assignment'):
if request.method == 'POST':
form = PollForm(request.POST, prefix="poll")
if form.is_valid():
poll.votesinvalid = form.cleaned_data['invalid'] or 0
poll.votescast = form.cleaned_data['votescast'] or 0
poll.save()
class ViewPoll(PollFormView):
poll_class = AssignmentPoll
template_name = 'assignment/poll_view.html'
def get_context_data(self, **kwargs):
context = super(ViewPoll, self).get_context_data(**kwargs)
self.assignment = self.poll.get_assignment()
context['application'] = self.assignment
return context
def get_success_url(self):
if not 'apply' in self.request.POST:
return reverse('assignment_view', args=[self.poll.assignment.id])
return ''
success = 0
for option in options:
option.form = OptionResultForm(request.POST, prefix="o%d" % option.id)
if option.form.is_valid():
option.voteyes = option.form.cleaned_data['yes']
option.voteno = option.form.cleaned_data['no'] or 0
option.voteundesided = option.form.cleaned_data['undesided'] or 0
option.save()
success = success + 1
if success == options.count():
messages.success(request, _("Votes are successfully saved.") )
if not 'apply' in request.POST:
return redirect(reverse('assignment_view', args=[assignment.id]))
else:
form = PollForm(initial={'invalid': poll.votesinvalid, 'votescast': poll.votescast}, prefix="poll")
for option in options:
option.form = OptionResultForm(initial={
'yes': option.voteyes,
'no': option.voteno,
'undesided': option.voteundesided,
}, prefix="o%d" % option.id)
return {
'poll': poll,
'form': form,
'options': options,
'ballotnumber': ballotnumber,
}
@permission_required('assignment.can_manage_assignment')
def set_published(request, poll_id, published=True):

View File

@ -17,8 +17,6 @@ from projector.api import register_slidemodel
from projector.models import Slide
class BaseOption(models.Model):
poll = models.ForeignKey('BasePoll')
@ -39,6 +37,9 @@ class Vote(models.Model):
weight = models.IntegerField(default=1)
value = models.CharField(max_length=255, null=True)
def __unicode__(self):
return print_value(self.weight)
class CountVotesCast(models.Model):
votescast = models.IntegerField(null=True, blank=True, verbose_name=_("Votes cast"))
@ -46,6 +47,9 @@ class CountVotesCast(models.Model):
def append_pollform_fields(self, fields):
fields.append('votescast')
def print_votescast(self):
return print_value(self.votescast)
class Meta:
abstract = True
@ -56,6 +60,9 @@ class CountInvalid(models.Model):
def append_pollform_fields(self, fields):
fields.append('votesinvalid')
def print_votesinvalid(self):
return print_value(self.votesinvalid)
class Meta:
abstract = True
@ -130,3 +137,10 @@ class BasePoll(models.Model, Slide):
register_slidemodel(BasePoll)
def print_value(value):
if value == -1:
return _('majority')
elif value == -2:
return _('undocumented')
return unicode(value)