Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No double votes #852

Merged
merged 4 commits into from Aug 15, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 0 additions & 3 deletions evap/evaluation/models.py
Expand Up @@ -509,9 +509,6 @@ def is_archived(self):
def is_archiveable(self):
return not self.is_archived and self.state in ["new", "published"]

def was_evaluated(self, request):
self.course_evaluated.send(sender=self.__class__, request=request, semester=self.semester)

@property
def final_grade_documents(self):
from evap.grades.models import GradeDocument
Expand Down
10 changes: 9 additions & 1 deletion evap/student/templates/student_vote.html
Expand Up @@ -108,6 +108,12 @@ <h2>{{ course.name }} ({{ course.semester.name }})</h2>
var form = $('#student-vote-form');
form.submit(function (event) {
event.preventDefault(); // don't use the default submission
var submitButton = $('#vote-submit-btn');
var originalText = submitButton.val();

submitButton.val("Submitting...");
submitButton.prop('disabled', true);

$.ajax({
type: form.attr('method'),
url: form.attr('action'),
Expand All @@ -122,8 +128,10 @@ <h2>{{ course.name }} ({{ course.semester.name }})</h2>
},
error: function(data) {
// show a warning if the post isn't successful
$('#vote-submit-btn').effect("highlight", {color:"#eb595a"}, 2000);
document.getElementById('submit-error-warning').style.display = 'block';
submitButton.effect("highlight", {color:"#eb595a"}, 2000);
submitButton.val(originalText);
submitButton.prop('disabled', false);
}
});
return false;
Expand Down
14 changes: 9 additions & 5 deletions evap/student/views.py
@@ -1,7 +1,7 @@
from collections import OrderedDict

from django.contrib import messages
from django.core.exceptions import PermissionDenied
from django.core.exceptions import PermissionDenied, SuspiciousOperation
from django.db import transaction
from django.shortcuts import get_object_or_404, redirect, render
from django.utils.translation import ugettext as _
Expand Down Expand Up @@ -83,6 +83,13 @@ def vote(request, course_id):

# all forms are valid, begin vote operation
with transaction.atomic():
# add user to course.voters
# not using course.voters.add(request.user) since it fails silently when done twice.
# manually inserting like this gives us the 'created' return value and ensures at the database level that nobody votes twice.
__, created = course.voters.through.objects.get_or_create(userprofile_id=request.user.pk, course_id=course.pk)
if not created: # vote already got recorded, bail out
raise SuspiciousOperation("A second vote has been received shortly after the first one.")

for contribution, form_group in form_groups.items():
for questionnaire_form in form_group:
questionnaire = questionnaire_form.questionnaire
Expand All @@ -102,10 +109,7 @@ def vote(request, course_id):
answer_counter.add_vote()
answer_counter.save()

# remember that the user voted already
course.voters.add(request.user)

course.was_evaluated(request)
course.course_evaluated.send(sender=Course, request=request, semester=course.semester)

messages.success(request, _("Your vote was recorded."))
return redirect('student:index')
Expand Down