2009-10-06 30 views
25

我正在制作一个小应用程序,让用户向上或向下投票项目。我正在使用Django(并且是新的!)。Django投票向上/向下方法

我只是想知道,什么是最好的方式向用户呈现upvote链接。作为链接,按钮或其他东西?

我已经在一个不同的框架在PHP中做了这样的事情,但我不知道我是否可以用同样的方法做到这一点。我应该有一个向上/向下投票的方法,然后显示一个链接指向用户点击。当他们点击它时,它会执行该方法并刷新页面?

回答

11

即插即用:

RedditStyleVoting
使用Django投票任何型号实现reddit的风格投票
http://code.google.com/p/django-voting/wiki/RedditStyleVoting

+0

这可能会有用。现在就看看它。你知道什么 从devdocs.apps.kb.models导入链接 应该改为? – 2009-10-07 13:20:51

+2

在我的回答中,优于代码的优点是渐进式增强 - 它可以在没有Javascript的情况下工作,但您可以在顶部添加AJAX以提供更好的用户体验。 – 2009-10-07 23:20:18

+3

将devdocs.apps.kb.models替换为您定义Link的models.py文件的路径。它会像yourprojectname.yourappname.models一样。 – 2009-10-07 23:22:53

4

作为一个链接,按钮或其他?

其他的东西,怎么样的形象?

当他们点击它时,它执行该方法并刷新页面?

也许你可以更好地使用ajax来调用一个方法来保存投票,而不是刷新任何东西。

这是我想到的。

enter image description here

8

不管你做什么,请确保它是由POST提交的,并没有得到; GET请求应该从不更改数据库信息。

+0

他是对的,这个原则排除使用简单的图像链接来重新加载页面。 – 2009-10-07 23:20:55

30

这里是我的解决方案的要点。我使用jQuery/AJAX来处理点击。受此网站的强烈影响。有些东西可能会使用一些工作(例如,客户端中的错误处理 - 其中大部分可能会被重构),但希望代码对您有用。

的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 --> 

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); 
       } 
      }); 
     } 
    }); 

,处理AJAX请求Django的观点:

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) 

和线程模型的相关部分:

class Thread(models.Model): 
    # ... 
    userUpVotes = models.ManyToManyField(User, blank=True, related_name='threadUpVotes') 
    userDownVotes = models.ManyToManyField(User, blank=True, related_name='threadDownVotes') 
+0

谢谢你。你把jQuery代码放在哪里? – 2009-10-07 11:27:03

+2

您在头文件中包含带有脚本标记的jquery.js文件,然后您可以将其粘贴到页面中任何位置的脚本标记中。我通常最终将它放在与页面那部分的HTML相同的django模板包含文件中,以便它们保持在一起。 如果你打算开始做AJAX-Y的话,jquery.com是一个很好的资源。 – 2009-10-07 23:17:25

+0

尝试了您的代码,但我无法获取可点击的按钮! – 2009-10-07 23:56:29