2012-02-24 10 views
0

私はDjango Webアプリケーションを作成していますが、このWebサイトに似ている投票システムがあります。jQueryを入手できませんAjax submit form with Django

現在、upvoteまたはdownvoteの矢印をクリックすると、jQueryを使用して色の変化と投票スコア(投票数)の変化を処理します。私は基本的に、元々データベースから取り出された投票スコアを取ってそれに応じて1つを追加または削除し、この数字を表示します。私はデータベースから得点を更新していないので、投票はユーザーに一貫しているように見える(ユーザーがサイトにいる間に他の人が投票をした場合)。

私はajaxの部分に問題があります。基本的に、ユーザーが投票すると、私はまだupvoteまたはdownvoteの送信をサーバーに送信し、データベースを更新したいが、ページを更新する必要はない。 Ajax呼び出しの最後に "return false"を追加しないと、データベースが更新されますが、ページが更新されます。しかし、Ajax呼び出しの最後に "return false"を追加すると、私のページはリフレッシュされませんが、データベースも更新されません。

<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> 

これは、2つのボタンを提出すると、フォームです::upvote用とdownvoteのための1

は、ここに私のフォームです。ここで

はあなたがupvoteボタンをクリックしたときのための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!"); 
      } 
      ) 


     }) 

基本的には、それの要旨はupvoteボタンが二つのクラスの1持つことができるということです。「uvpote_off」または「upvote_on」を、ユーザーがアップvしたかどうかによって異なります。 if elseステートメントは、これらのステートが正しく変更されただけです。問題はここにあるされ、正確に何

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,))) 

ここでは、フォームが送信さに私のDjangoのビュー関数は、ありますか?私はここ数時間、この問題に苦労していて、チュートリアルをたくさん見ましたが、私が間違っていることを理解することはできません。

ご協力いただきありがとうございます。

答えて

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; 

}) 

サイト上のフォームの数があるので、私は私が保証するためにクリックして送信ボタンの親からURLを取得しましたそれは正しい形式でした。私は公式のDjango docusにここに示すように、他のものは、すべてのポストを要求と共に、CSRFトークンを渡すことについてだった私の要求はすべて「/文/投票//」だったことに気付いた後

これを実現: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() 

あなたはまずVを削除することができます。(保存)し、ブロックを除いて試してみるのうちの第二1を移動:私もupvoteとdownvoteはほとんど同じことだと思い

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

、そしてあなたはあなたのために、この動作をインスタンス化するクラスを作成することを検討すべきですので、多くの行を書く必要はありません。私は6-8があまり好きではないと思いますが、入るのはいい習慣です。これを行う

: リターンHttpResponseRedirect( 'sentence.views.show_sentence_order'(リバース引数=(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

+0

@WarAndPiece私の投稿が参考になった場合は、ありがとう、答えを受け入れて投票してください。 –