2012-02-24 50 views
0

我创建一个Django的web应用程序其特点类似,这是什么网站上投票系统工作。无法获取的jQuery的Ajax提交表单和Django

目前,当你点击一个给予好评或downvote箭,我使用jQuery来处理颜色的变化,并在投票评分的变化(投票数)。我基本上将原来从数据库中提取的投票分数相应地加上或减去一个,然后显示这个数字。我没有更新数据库中的分数,因此投票似乎与用户一致(如果其他人在用户在网站上投了票)。

我有阿贾克斯部分的麻烦。基本上,当用户投票,我还是想送给予好评或downvote提交到服务器并更新数据库,但没有刷新页面。当我不添加“返回false”到ajax调用结束时,我的数据库被更新,但是我的页面刷新了。但是,当我将“返回false”添加到ajax调用的结尾时,我的页面不会刷新,但数据库也不会更新。

这里是我的形式:

<form method="post" class="voting-button" action="/sentence/vote/{{sentence.id}}/"> 
        {% csrf_token %} 
        <input type="submit" class="upvote_on" name="upvote" value="" /> 
        <p class="vote-score">{{sentence.total_votes}}</p> 
        <input type="submit" class="downvote_off" name="downvote" value="" /> 
       </form> 

它与两个提交按钮的一种形式:一个是给予好评,一个用于downvote。

这是因为当你点击给予好评按钮的javascript:

<script type="text/javascript">   
    //script to control arrows and the number of votes shown 
     $("[name='upvote']").click(function(){ 
      if ($(this).attr("class") == "upvote_off") { 
       $(this).attr("class", "upvote_on"); 

       //If upvote is off and downvote is off 
       if ($(this).siblings("[name='downvote']").attr("class") == "downvote_off"){ 
        var score = $(this).siblings(".vote-score").text(); 
        scoreInt = parseInt(score) 
        scoreInt += 1; 
        $(this).siblings(".vote-score").text(scoreInt); 
       } else { //if upvote is off and downvote is on 
        var score = $(this).siblings(".vote-score").text(); 
        scoreInt = parseInt(score) 
        scoreInt += 2; 
        $(this).siblings(".vote-score").text(scoreInt); 
       } 

       $(this).siblings("[name='downvote']").attr("class", "downvote_off"); 

      } else { 
       $(this).attr("class", "upvote_off");  

       $(this).siblings("[name='downvote']").attr("class", "downvote_off"); 

       var score = $(this).siblings(".vote-score").text(); 
       scoreInt = parseInt(score) 
       scoreInt -= 1; 
       $(this).siblings(".vote-score").text(scoreInt); 
      } 



      $.post(

      '/sentence/vote/{{sentence.id}}/', 
      { 
      name: "upvote", 
      }, 

      function(response){ 
       $("#divText").text("hello world!"); 
      } 
      ) 


     }) 

基本上,它的主要内容是,给予好评按钮可以有两种类别之一:“uvpote_off”或“upvote_on”取决于用户是否上传或不提供。 if else语句只是为了使这些状态改变正确。

这里是我的Django的查看功能,其形式发送至:

def vote(request, sentence_id): 
p = get_object_or_404(Sentence, pk=sentence_id) 

if 'upvote' in request.POST: 
    try: 
     v = Vote.objects.filter(voter = request.user).get(sentence=p) 
     if v.score == 0: 
      v.score = 1 
     elif v.score == 1: 
      v.score = 0 
     else: #for case where v.score = -1 
      v.score = 1 
     v.save() 
    except Vote.DoesNotExist: 
     v = Vote(voter =request.user, sentence=p, score=1) 
     v.save() 

elif 'downvote' in request.POST: 
    try: 
     v = Vote.objects.filter(voter = request.user).get(sentence=p) 
     if v.score == 0: 
      v.score = -1 
     elif v.score == -1: 
      v.score = 0 
     else: #for case where v.score = 1 
      v.score = -1 
     v.save() 
    except Vote.DoesNotExist: 
     v = Vote(voter = request.user, sentence=p, score=1) 
     v.save() 


return HttpResponseRedirect(reverse('sentence.views.show_sentence_order', args=(p.sentence_order,))) 

到底是什么问题就在这里?过去几个小时我一直在为此苦苦挣扎,看了一大堆教程,但无法弄清楚我做错了什么。

非常感谢您的帮助。

回答

0

好吧,我终于得到了我想要的工作。我之前的代码有一些错误,其中一个是在$.post函数中,我传递了url '/sentence/vote/{{sentence.id}}/'

但是,这是我应该做的:

var loadURL = $(this).parent().attr("action"); 
    $.ajax({ 
       type: "POST", 
       url: loadURL, 
       data: loadData, 

    }); // End .ajax function 

return false; 

}) 

因为有一些网站上的表格,我不得不从提交按钮,我点击,以确保母公司抢网址这是正确的形式。我意识到这注意到我的要求都是“/句子/票//”

那么另一件事是关于通过的CSRF令牌,与每一个岗位请求一起,如下所示的Django官方docus后:https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax

我不得不承认我没有完全理解这一点,但我将代码复制到我的脚本块中,现在它正在工作。

0

有几件事情,我从你的例子指出,其中的一些只是我对效率的观点:

def vote(request, sentence_id): 
    p = get_object_or_404(Sentence, pk=sentence_id) 

如果这是一个Ajax调用,而不是用于别的,你不需要get_object函数。刚刚得到的对象,因为你知道投票对象存在,因为你通过它。我想,但是,使用if request.is_ajax()方法,提高500除外。

v = Vote.objects.filter(voter = request.user).get(sentence=p) 

,而不是你可以写:

v = Vote.objects.get(voter = request.user,sentence=p) 

这里:

v.save() 
except Vote.DoesNotExist: 
    v = Vote(voter =request.user, sentence=p, score=1) 
    v.save() 

您可以删除第一个诉save()和移动第二个出来的尝试,除了块:

except Vote.DoesNotExist: 
    v = Vote(voter =request.user, sentence=p, score=1) 
v.save() 

我也觉得给予好评和downvote是几乎同样的事情,你应该考虑创建一个实例化这个行为,你一个类,所以你不必写多少行。我意识到6-8听起来不怎么样,但这是一个很好的习惯。

这样做: 返回HttpResponseRedirect(反向( 'sentence.views.show_sentence_order',ARGS =(p.sentence_order,)))

将发送给一些其它的URL和视图的响应。我不确定show_sentence_order会做什么,因为您没有发布它,但我认为它会刷新页面。

当发送Ajax回客户端,你只需做一些事情,这将是这样的:

return HttpResponse(some_object_probably_json_here, mimetype="application/json") 

当然,你需要从你的JavaScript调用抓住它,我不能看到你这是否即将发生。

我强烈建议你阅读这个网站:

http://lethain.com/intro-to-unintrusive-javascript-with-django/

,并在整个教程步进。

+0

嘿詹姆斯,谢谢你的效率指针。这实际上是我第一次编写一个Django应用程序,所以仍然没有一个非常有效的代码设计。该教程非常有趣,它回答了我在django中设置ajax的许多问题。主要问题实际上是将csrf_token作为POST数据传递:https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax。我会把它作为答案进一步详细说明。 – WarAndPiece 2012-02-24 23:06:55

+0

@WarAndPiece谢谢你,如果我的帖子很有帮助,请接受答案并投票,如果不是,请保持原状;) – 2012-02-24 23:09:15