Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Vote Up/Down method [closed]

I am making a small app that lets users vote items either up or down. I'm using Django (and new to it!).

I am just wondering, what is the best way to present the upvote link to the user. As a link, button or something else?

I have already done something like this in php with a different framework but I'm not sure if I can do it the same way. Should I have a method for up/down vote and then display a link to the user to click. When they click it, it performs the method and refreshes the page?

like image 612
irl_irl Avatar asked Oct 06 '09 23:10

irl_irl


2 Answers

Here's the gist of my solution. I use images with jQuery/AJAX to handle clicks. Strongly influenced by this site. There's some stuff that could use some work (error handling in the client, for example -- and much of it could probably be refactored) but hopefully the code is useful to you.

The HTML:

        <div class="vote-buttons">         {% ifequal thisUserUpVote 0 %}         <img class="vote-up" src = "images/vote-up-off.png" title="Vote this thread UP. (click again to undo)" />         {% else %}         <img class="vote-up selected" src = "images/vote-up-on.png" title="Vote this thread UP. (click again to undo)" />         {% endifequal %}         {% ifequal thisUserDownVote 0 %}         <img class="vote-down" src = "images/vote-down-off.png" title="Vote this thread DOWN if it is innapropriate or incorrect. (click again to undo)" />         {% else %}         <img class="vote-down selected" src = "images/vote-down-on.png" title="Vote this thread DOWN if it is innapropriate or incorrect. (click again to undo)" />         {% endifequal %}         </div> <!-- .votebuttons --> 

The jQuery:

$(document).ready(function() {      $('div.vote-buttons img.vote-up').click(function() {          var id = {{ thread.id }};         var vote_type = 'up';          if ($(this).hasClass('selected')) {             var vote_action = 'recall-vote'             $.post('/ajax/thread/vote', {id:id, type:vote_type, action:vote_action}, function(response) {                 if (isInt(response)) {                     $('img.vote-up').removeAttr('src')                         .attr('src', 'images/vote-up-off.png')                         .removeClass('selected');                     $('div.vote-tally span.num').html(response);                 }             });         } else {              var vote_action = 'vote'             $.post('/ajax/thread/vote', {id:id, type:vote_type, action:vote_action}, function(response) {                 if (isInt(response)) {                     $('img.vote-up').removeAttr('src')                         .attr('src', 'images/vote-up-on.png')                         .addClass('selected');                     $('div.vote-tally span.num').html(response);                 }             });         }     }); 

The Django view that handles the AJAX request:

def vote(request):    thread_id = int(request.POST.get('id'))    vote_type = request.POST.get('type')    vote_action = request.POST.get('action')     thread = get_object_or_404(Thread, pk=thread_id)     thisUserUpVote = thread.userUpVotes.filter(id = request.user.id).count()    thisUserDownVote = thread.userDownVotes.filter(id = request.user.id).count()     if (vote_action == 'vote'):       if (thisUserUpVote == 0) and (thisUserDownVote == 0):          if (vote_type == 'up'):             thread.userUpVotes.add(request.user)          elif (vote_type == 'down'):             thread.userDownVotes.add(request.user)          else:             return HttpResponse('error-unknown vote type')       else:          return HttpResponse('error - already voted', thisUserUpVote, thisUserDownVote)    elif (vote_action == 'recall-vote'):       if (vote_type == 'up') and (thisUserUpVote == 1):          thread.userUpVotes.remove(request.user)       elif (vote_type == 'down') and (thisUserDownVote ==1):          thread.userDownVotes.remove(request.user)       else:          return HttpResponse('error - unknown vote type or no vote to recall')    else:       return HttpResponse('error - bad action')      num_votes = thread.userUpVotes.count() - thread.userDownVotes.count()     return HttpResponse(num_votes) 

And the relevant parts of the Thread model:

class Thread(models.Model):     # ...     userUpVotes = models.ManyToManyField(User, blank=True, related_name='threadUpVotes')     userDownVotes = models.ManyToManyField(User, blank=True, related_name='threadDownVotes') 
like image 127
Matt Miller Avatar answered Sep 25 '22 19:09

Matt Miller


Just plug and play:

RedditStyleVoting
Implementing reddit style voting for any Model with django-voting
http://code.google.com/p/django-voting/wiki/RedditStyleVoting

like image 39
panchicore Avatar answered Sep 21 '22 19:09

panchicore