2012-02-24 25 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