This is a dirty/untested theoretical implementation using jQuery/Django.
We're going to assume the voting up and down is for questions/answers like on this site, but that can obviously be adjusted to your real life use case.
The template
<div id="answer_595" class="answer">
<img src="vote_up.png" class="vote up">
<div class="score">0</div>
<img src="vote_down.png" class="vote down">
Blah blah blah this is my answer.
</div>
<div id="answer_596" class="answer">
<img src="vote_up.png" class="vote up">
<div class="score">0</div>
<img src="vote_down.png" class="vote down">
Blah blah blah this is my other answer.
</div>
Javascript
$(function() {
$('div.answer img.vote').click(function() {
var id = $(this).parents('div.answer').attr('id').split('_')[1];
var vote_type = $(this).hasClass('up') ? 'up' : 'down';
if($(this).hasClass('selected')) {
$.post('/vote/', {id: id, type: vote_type}, function(json) {
if(json.success == 'success') {
$('#answer_' + id)
.find('img.' + vote_type);
.attr('src', 'vote_' + vote_type + '_selected.png')
.addClass('selected');
$('div.score', '#answer_' + id).html(json.score);
}
});
} else {
$.post('/remove_vote/', {id: id, type: vote_type}, function(json) {
if(json.success == 'success') {
$('#answer_' + id)
.find('img.' + vote_type);
.attr('src', 'vote_' + vote_type + '.png')
.removeClass('selected');
$('div.score', '#answer_' + id).html(json.score);
}
});
}
});
});
Django views
def vote(request):
if request.method == 'POST':
try:
answer = Answer.objects.get(pk=request.POST['id'])
except Answer.DoesNotExist:
return HttpResponse("{'success': 'false'}")
try:
vote = Vote.objects.get(answer=answer, user=request.user)
except Vote.DoesNotExist:
pass
else:
return HttpResponse("{'success': 'false'}")
if request.POST['type'] == 'up':
answer.score = answer.score + 1
else:
answer.score = answer.score - 1
answer.save()
Vote.objects.create(answer=answer,
user=request.user,
type=request.POST['type'])
return HttpResponse("{'success':'true', 'score':" + answer.score + "}")
else:
raise Http404('What are you doing here?')
def remove_vote(request):
if request.method == 'POST':
try:
answer = Answer.objects.get(pk=request.POST['id'])
except Answer.DoesNotExist:
return HttpResponse("{'success': 'false'}")
try:
vote = Vote.objects.get(answer=answer, user=request.user)
except Vote.DoesNotExist:
return HttpResponse("{'success': 'false'}")
else:
vote.delete()
if request.POST['type'] == 'up':
answer.score = answer.score - 1
else:
answer.score = answer.score + 1
answer.save()
return HttpResponse("{'success':'true', 'score':" + answer.score + "}")
else:
raise Http404('What are you doing here?')
Yikes. When I started answering this question I didn't mean to write this much but I got carried away a little bit. You're still missing an initial request to get all the votes when the page is first loaded and such, but I'll leave that as an exercise to the reader. Anyhow, if you are in fact using Django and are interested in a more tested/real implemention of the Stackoverflow voting, I suggest you check out the source code for cnprog.com, a Chinese clone of Stackoverflow written in Python/Django. They released their code and it is pretty decent.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…