Django投票Up/Down方法

irl*_*irl 27 python django voting

我正在制作一个小应用程序,允许用户向上或向下投票.我正在使用Django(和它一样新!).

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

我已经在php中使用不同的框架做了类似的事情,但我不确定我是否能以同样的方式做到这一点.我应该有一个上/下投票的方法,然后显示一个链接到用户点击.当他们点击它时,它会执行该方法并刷新页面?

Mat*_*ler 33

这是我的解决方案的要点.我使用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 -->
Run Code Online (Sandbox Code Playgroud)

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);
                }
            });
        }
    });
Run Code Online (Sandbox Code Playgroud)

处理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)
Run Code Online (Sandbox Code Playgroud)

以及Thread模型的相关部分:

class Thread(models.Model):
    # ...
    userUpVotes = models.ManyToManyField(User, blank=True, related_name='threadUpVotes')
    userDownVotes = models.ManyToManyField(User, blank=True, related_name='threadDownVotes')
Run Code Online (Sandbox Code Playgroud)

  • 谢谢.我喜欢看到完整的解决方案+1 (5认同)
  • 您在标题中包含带有脚本标记的jquery.js文件,然后您可以将此标记粘贴在页面中的任何位置.我通常最终将它放在相同的django模板包含文件中,作为页面该部分的HTML,以便它们保持在一起.如果你要开始做AJAX-y的东西,jquery.com是一个很好的资源. (2认同)

pan*_*ore 12

即插即用:

RedditStyleVoting
使用django-voting为任何模型实现reddit样式投票
http://code.google.com/p/django-voting/wiki/RedditStyleVoting

  • 将devdocs.apps.kb.models替换为您定义Link的models.py文件的路径.它将类似于yourprojectname.yourappname.models. (3认同)
  • 这个代码在我的答案中的优势是渐进式增强 - 它可以在没有Javascript的情况下工作,但是你可以在顶部添加AJAX以提供更好的用户体验. (2认同)

小智 10

无论你做什么,确保它是由POST提交而不是GET; GET请求永远不应该改变数据库信息.


Osc*_*Ryz 7

作为链接,按钮或其他?

其他什么,图像怎么样?

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

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

这就是我想到的.

在此输入图像描述