Django 投票方法

61 阅读1分钟

我在创建一个小程序,允许用户对项目进行投票。我正在使用 Django(并且是新手),并且想知道向用户显示投票链接的最佳方式是什么。是作为链接、按钮还是其他东西?

  1. 解决方案
  • 使用 jQuery/AJAX 处理点击的图像。 这将允许您在不刷新页面的情况下记录投票。
  • 在服务器端有一个视图来处理 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);
        }
      });
    }
  });

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)

Thread 模型

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