summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoretienne2008-12-07 19:06:22 +0000
committeretienne2008-12-07 19:06:22 +0000
commita837805ddb218af008f06adb57439949ae32582f (patch)
tree9f58533cf4c63b45b96e58f95f273dc70fb49a9b
parent8c5c770d99f2d59ffe487ed0fdbe6a06139f3f49 (diff)
Modifying limits - Reordering of choices
-rw-r--r--polls/models.py40
-rw-r--r--polls/views.py82
-rw-r--r--static/styles.css9
-rw-r--r--templates/createOrEdit.html8
-rw-r--r--templates/vote.html2
5 files changed, 119 insertions, 22 deletions
diff --git a/polls/models.py b/polls/models.py
index 7128e0d..dac3d39 100644
--- a/polls/models.py
+++ b/polls/models.py
@@ -72,6 +72,13 @@ class Voter(models.Model):
ordering = ['creation_date']
def __unicode__(self):
return _("Vote from %(user)s") % {'user':self.user.name}
+ def getVotes(self, choice_ids):
+ '''Get votes for a subset of choices
+ '''
+ query = Vote.objects.filter(voter=self)
+ query = query.extra(where=['choice_id IN (%s)' \
+ % ",".join([str(choice_id) for choice_id in choice_ids])])
+ return list(query.order_by('choice'))
class Choice(models.Model):
poll = models.ForeignKey(Poll)
@@ -84,10 +91,41 @@ class Choice(models.Model):
class Meta:
ordering = ['order']
+ def getSum(self):
+ '''Get the sum of votes for this choice'''
+ sum = 0
+ for vote in Vote.objects.filter(choice=self):
+ sum += vote.value
+ return sum
+
+ def changeOrder(self, idx=1):
+ '''
+ Change a choice in the list
+ '''
+ if (self.order + idx) < 0:
+ return
+ choices = Choice.objects.filter(poll=self.poll)
+ if self.order + idx > len(choices):
+ return
+ new_order = self.order + idx
+ for choice in choices:
+ if choice == self:
+ continue
+ if idx < 0 and choice.order < self.order \
+ and choice.order >= new_order:
+ choice.order += 1
+ choice.save()
+ if idx > 0 and choice.order > self.order \
+ and choice.order <= new_order:
+ choice.order -= 1
+ choice.save()
+ self.order = new_order
+ self.save()
+
class Vote(models.Model):
voter = models.ForeignKey(Voter)
choice = models.ForeignKey(Choice)
VOTE = ((1, (_('Yes'), _('Yes'))),
(0, (_('No'), _('Maybe')), ),
(-1, (_('No'), _('No'))),)
- value = models.IntegerField(choices=VOTE, blank=True, null=True)
+ value = models.IntegerField(choices=VOTE, blank=True, null=True) \ No newline at end of file
diff --git a/polls/views.py b/polls/views.py
index e969a74..ad7e94f 100644
--- a/polls/views.py
+++ b/polls/views.py
@@ -117,7 +117,8 @@ def createOrEdit(request, admin_url):
admin_url = 'a' + genRandomURL()
category = None
if 'poll_category' in request.POST and request.POST['poll_category']:
- category = Category.objects.get(id=int(request.POST['poll_category']))
+ category = \
+ Category.objects.get(id=int(request.POST['poll_category']))
public = False
if 'poll_public' in request.POST and request.POST['poll_public']:
value = False
@@ -195,6 +196,23 @@ public=public)
choice = Choice(poll=poll, name=request.POST['new_choice'],
order=order, limit=limit)
choice.save()
+ # check if the order of a choice has to be changed
+ for key in request.GET:
+ try:
+ if 'up_choice' in key:
+ choice = Choice.objects.get(id=int(request.GET[key]))
+ choice.changeOrder(-1)
+ # redirect in order to avoid a change with a refresh
+ url = response_dct['admin_url']
+ return response_dct, HttpResponseRedirect(url)
+ if 'down_choice' in key:
+ choice = Choice.objects.get(id=int(request.GET[key]))
+ choice.changeOrder(1)
+ # redirect in order to avoid a change with a refresh
+ url = response_dct['admin_url']
+ return response_dct, HttpResponseRedirect(url)
+ except (ValueError, Choice.DoesNotExist):
+ pass
# check if a choice has been choosen for deletion or for modification
for key in request.POST:
if key.startswith('delete_') and request.POST[key]:
@@ -209,6 +227,31 @@ public=public)
except Choice.DoesNotExist:
# throw when want to modify a deleted choice
pass
+
+ if key.startswith('limit_'):
+ #request.POST[key]:
+ try:
+ choice = Choice.objects.get(id=int(key[len('limit_'):]))
+ if not request.POST[key]:
+ choice.limit = None
+ choice.save()
+ else:
+ try:
+ new_limit = int(request.POST[key])
+ sum = choice.getSum()
+ if new_limit < sum:
+ response_dct['error'] = _("You cannot lower %s\
+'s limit to this number : there is currently %d votes for this choice.") % (
+ choice.name, sum)
+ else:
+ choice.limit = new_limit
+ choice.save()
+ except ValueError:
+ response_dct['error'] = _("Non-numeric value for \
+limit")
+ except Choice.DoesNotExist:
+ # throw when want to modify a deleted choice
+ pass
return response_dct, None
response_dct, redirect = getBaseResponse(request)
@@ -422,21 +465,21 @@ def poll(request, poll_url):
# get voters and sum for each choice for this poll
voters = Voter.objects.filter(poll=poll)
- for choice in choices:
- choice.sum = 0
- max = -100
- max_ids = []
+ #for choice in choices:
+ # choice.sum = 0
+ #max = -100
+ #max_ids = []
choice_ids = [choice.id for choice in choices]
for voter in voters:
# highlight a voter
if time.mktime(voter.modification_date.timetuple()) \
== highlight_vote_date:
voter.highlight = True
- query = Vote.objects.filter(voter=voter)
- query = query.extra(where=['choice_id IN (%s)' \
- % ",".join([str(choice.id) for choice in choices])])
- voter.votes = list(query.order_by('choice'))
- for vote in voter.votes:
+ #query = Vote.objects.filter(voter=voter)
+ #query = query.extra(where=['choice_id IN (%s)' \
+ # % ",".join([str(choice.id) for choice in choices])])
+ voter.votes = voter.getVotes(choice_ids)
+ """for vote in voter.votes:
if vote.choice.id in choice_ids:
if vote.value:
c_id = choice_ids.index(vote.choice.id)
@@ -447,9 +490,10 @@ def poll(request, poll_url):
elif choices[c_id].sum == max:
max_ids.append(c_id)
else:
+ if vote.choice.id not in choice_ids:
# the choice is probably not available anymore
voter.votes.remove(vote)
- vote.delete()
+ vote.delete()"""
# initialize undefined vote
choice_vote_ids = [vote.choice.id for vote in voter.votes]
for choice in choices:
@@ -458,14 +502,24 @@ def poll(request, poll_url):
vote.save()
idx = choices.index(choice)
voter.votes.insert(idx, vote)
- for max_id in max_ids:
- choices[max_id].highlight = True
+ #for max_id in max_ids:
+ # choices[max_id].highlight = True
+ sums = [choice.getSum() for choice in choices]
+ vote_max = max(sums)
+ c_idx = 0
+ while c_idx < len(choices):
+ try:
+ c_idx = sums.index(vote_max, c_idx)
+ choices[c_idx].highlight = True
+ c_idx += 1
+ except ValueError:
+ c_idx = len(choices)
# set non-available choices if the limit is reached for a choice
response_dct['limit_set'] = None
for choice in choices:
if choice.limit:
response_dct['limit_set'] = True
- if choice.limit and choice.sum >= choice.limit:
+ if choice.limit and sums[choices.index(choice)] >= choice.limit:
choice.available = False
else:
choice.available = True
diff --git a/static/styles.css b/static/styles.css
index 421b93f..64eb77b 100644
--- a/static/styles.css
+++ b/static/styles.css
@@ -138,7 +138,7 @@ color:grey;
text-decoration:none;
}
-.alert{
+.alert, .error{
color:blue;
}
@@ -150,7 +150,7 @@ width:600px;
width:160px;
}
-.new_poll input#limit{
+.new_poll input.limit{
width:20px;
}
@@ -166,6 +166,11 @@ font-size:11px;
width:200px;
}
+a.arrow{
+text-decoration:None;
+font-weight:bold;
+}
+
#content{
margin:5px;
}
diff --git a/templates/createOrEdit.html b/templates/createOrEdit.html
index 033edec..e4d9639 100644
--- a/templates/createOrEdit.html
+++ b/templates/createOrEdit.html
@@ -5,8 +5,8 @@
{% if not new and not choices %}
<p class='error'>{% trans "As long as no options were added to the poll, it will not be made available." %}</p>
{% endif %}
- <h2>{% if new %}{% trans "New poll" %}{% else %}{% trans "Edit poll" %}{% endif %}</h2>
{% if error %}<p class='error'>{{ error }}</p>{% endif %}
+ <h2>{% if new %}{% trans "New poll" %}{% else %}{% trans "Edit poll" %}{% endif %}</h2>
<table class='new_poll'>
<form action="{{admin_url}}" method="post">
@@ -104,10 +104,10 @@
<table class='new_poll'>
{% if choices %}<form action="{{admin_url}}" method="post">
<tr>
- <th>{% trans "Choices" %}</th><th>{% trans "Label" %}</th><th>{% trans "Limit" %}</th><th>{% trans "Delete?"%}</th>
+ <th>{% trans "Up/down" %}</th><th>{% trans "Label" %}</th><th>{% trans "Limit" %}</th><th>{% trans "Delete?"%}</th>
</tr>
{% for choice in choices %}<tr>
- <td>&nbsp;</td><td><input type='text' name='modify_{{choice.id}}' value="{{choice.name}}"/></td><td>{%if choice.limit%}{% blocktrans with choice.limit as choice_limit%}Limited to {{choice_limit}} vote(s){% endblocktrans %}{%endif%}</td><td><input type='checkbox' name='delete_{{choice.id}}'/></td>
+ <td><a href='?up_choice={{choice.id}}' class='arrow'>+</a> / <a href='?down_choice={{choice.id}}' class='arrow'>-</a></td><td><input type='text' name='modify_{{choice.id}}' value="{{choice.name}}"/></td><td>{% trans "Limited to"%} <input type='text' name='limit_{{choice.id}}' class='limit'{%if choice.limit%} value='{{choice.limit}}'{%endif%}/> {% trans "vote(s)" %}</td><td><input type='checkbox' name='delete_{{choice.id}}'/></td>
</tr>{% endfor %}
<tr>
<td></td>
@@ -117,7 +117,7 @@
</form>{% endif %}
<form action="{{admin_url}}" method="post">
- <tr><td><label>{% trans "New choice" %}</label></td><td><input type='text' name='new_choice'/></td><td>{%trans "Limited to"%} <input type='text' name='limit' id='limit'/> {%trans "vote(s)"%}</td><td class='form_description'>{% trans "Setting a new choice. Optionally you can set a limit of vote for this choice. This limit is usefull for limited resources allocation." %}</td></tr>
+ <tr><td><label>{% trans "New choice" %}</label></td><td><input type='text' name='new_choice'/></td><td>{%trans "Limited to"%} <input type='text' name='limit' class='limit'/> {%trans "vote(s)"%}</td><td class='form_description'>{% trans "Setting a new choice. Optionally you can set a limit of vote for this choice. This limit is usefull for limited resources allocation." %}</td></tr>
<tr>
<td></td>
<td><input type='hidden' name='add' value='1'/> <input type='submit' value='{% trans "Add" %}' /></td>
diff --git a/templates/vote.html b/templates/vote.html
index 21b8a0d..b9cfa98 100644
--- a/templates/vote.html
+++ b/templates/vote.html
@@ -77,7 +77,7 @@
{%endif%}{%endif%}
{% if not hide_vote %}<tr id='sum'>
<td class='simple'></td><th>{% trans "Sum" %}</th>
- {% for choice in choices %}<td{%if choice.highlight %} class='highlight'{%endif%}>{{choice.sum}}</td>
+ {% for choice in choices %}<td{%if choice.highlight %} class='highlight'{%endif%}>{{choice.getSum}}</td>
{% endfor %}
</tr>{%endif%}
</table>