【问题标题】:Voting/unvoting system with AJAX使用 AJAX 的投票/取消投票系统
【发布时间】:2015-07-04 06:23:46
【问题描述】:

我使用 AJAX 在 Django 上实现了一个投票/取消投票系统,如下所示:

views.py

@login_required
def vote(request):
    post_id = None
    if request.method == 'GET':
        post_id = request.GET['post_id']

    if post_id:
        post = Post.objects.get(id=int(post_id))
        current_user = request.user.id

    try:
        voted = Vote.objects.get(post=post, user=current_user)
    except Vote.DoesNotExist:
        voted = None

    # Voting code

    if not voted:
        Vote.objects.get_or_create(post=post, user=request.user)
        post.points = post.vote_set.all().count()
        post.save()
        print("voted!")

    return HttpResponse(post.points)

@login_required
def unvote(request):
    post_id = None
    if request.method == 'GET':
        post_id = request.GET['post_id']

    if post_id:
        post = Post.objects.get(id=int(post_id))
        current_user = request.user.id

    try:
        voted = Vote.objects.get(post=post, user=current_user)
    except Vote.DoesNotExist:
        voted = None

    # Voting code

    if voted:
        Vote.objects.filter(post=post, user=request.user).delete()
        post.points = post.vote_set.all().count()
        post.save()
        print("unvoted!")

    return HttpResponse(post.points)

ma​​in.js

// Voting
$('.vote').click(function(){
    var postid;
    postid = $(this).attr("data-postid");
    $.get('/vote/', {post_id: postid}, function(data){ //Send post_id to vote view
        $('#points' + postid).html(data); // Data changed element
        $('#' + postid).attr('class', 'voted');
    });
});

// Unvoting
$('.voted').click(function(){
    var postid;
    postid = $(this).attr("data-postid");
    $.get('/unvote/', {post_id: postid}, function(data){ //Send post_id to unvote view
        $('#points' + postid).html(data); // Data changed element
        $('#' + postid).attr('class', 'vote');
    });
});

投票工作正常,但我必须刷新页面才能取消投票。以及取消投票然后再次投票。这是怎么回事?

【问题讨论】:

    标签: ajax django


    【解决方案1】:

    问题是当您加载页面时,只有一个元素具有votevoted 类。您应该添加一个类,比如votable,然后执行以下操作:

    $('.votable').click(function(){
        var element = $(this),
            postid = element.attr("data-postid");
    
        if (element.hasClass('voted')) {
            // Unvoting
            $.get('/unvote/', {post_id: postid}, function(data) { //Send post_id to unvote view
                $('#points' + postid).html(data); // Data changed element
                $('#' + postid).removeClass('voted');
            }); 
        } else {
            // Voting
            $.get('/vote/', {post_id: postid}, function(data) { //Send post_id to vote view
                $('#points' + postid).html(data); // Data changed element
                $('#' + postid).addClass('voted');
            });
        }
    

    【讨论】:

      【解决方案2】:

      click() 函数绑定到 click 事件是一个直接绑定,它只会将 on click 事件处理程序附加到已经存在的元素上,它既不会绑定到将来创建的元素上,也不会绑定到您正在选择的元素上您正在动态添加或删除的属性(在本例中为类)。

      以下 .on() 方法将在整个动态变化中起作用。

      $(document).on('click','.vote', function() {
          //Do Stuff
      });
      

      作为一般规则,通过您希望通过代码动态添加和删除的特定类访问元素是有问题的做法。您应该通过 id 或 name 或您不会添加和删除的类来访问元素,它简化了整体结构。

      如果您通过$(document).on('click','#yourId', function(){}); 访问您的元素,它将清除您可能遇到的一些问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-22
        • 1970-01-01
        • 1970-01-01
        • 2015-01-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多