diff options
-rw-r--r-- | polls/models.py | 40 | ||||
-rw-r--r-- | polls/views.py | 82 | ||||
-rw-r--r-- | static/styles.css | 9 | ||||
-rw-r--r-- | templates/createOrEdit.html | 8 | ||||
-rw-r--r-- | templates/vote.html | 2 |
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> </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> |