2017-08-24 10 views
1

ユーザーがドラッグアンドドロップできるjquery要素を使用しています。私はajaxを使ってdjangoに要素の順序を投稿します。django形式のjquery要素

djangoビューの中で、私はajaxから投稿されたデータを扱うことができます。

Djangoのビュー:

#this is the view where the jquery elements are being ordered by the user 
def inside_exam(request): 


    if request.method=='POST': 
     form = MyForm(request.POST) 
     if form.is_valid(): 
      #here I am able to retrieve the data from ajax and save it to a django model, code not shown here 

      return redirect('exam_results') 


#the view redirected to from the inside_exam view 
def exam_results(request): 

    #here I set the score for the exam and set the context, code not shown here 

    print(“all is set”) 
    return render(request, 'quizresults.html', context) 

プリントは(「すべてが設定されている」)を実行し、私は、ブラウザでquizresults.htmlのHTMLを印刷することができています。端末ウィンドウにエラーはありません。これは端末に表示されます: "GET/exam_results/HTTP/1.1" 200 8981.

同じテンプレートが表示されても、quizresults.htmlテンプレートは表示されません。 render(request、 'quizresults.html'、context)が期待どおりに動作しない理由は何ですか?

ところで:jqueryなしでdjangoフォームを使用すると、すべて正常に動作し、quizresults.htmlテンプレートが表示されます。

私はユーザーに別のテンプレートを表示したいが、現在のテンプレートを更新しないので、ajaxはこの場合jqueryデータを送信する正しい方法ではないかもしれませんか?そうでない場合は、より良い方法は何でしょうか?

編集、AJAXコード:ジャンゴでredirectショートカット方法を使用

function dataToSend() { 
    {% load static %} 
    var node2 = document.getElementById('sortable'); 
    var idsInOrder = $("#sortable").sortable('toArray'); 
    console.log("the ids"); 
    console.log(idsInOrder); 

    var fd = new FormData(); 
    for(var i=0; i<idsInOrder.length; i++) { 
      j = i+1 
      fd.append('a'+j, idsInOrder[i]); 
    } 

    $.ajax({ 
     type: 'POST', 
     data: fd, 
     cache: false, 
     processData: false, 
     contentType: false 
    }).done(function(data) { 
     //The data from the quizresults.html template is printed out here, but that template is not shown, the template in the browser is still the insidequiz.html template. 
     console.log("the data"); 
     console.log(data); 
    }); 
} 


window.onload = function init() { 
    function getCookie(name) { 
     var cookieValue = null; 
     if (document.cookie && document.cookie !== '') { 
     var cookies = document.cookie.split(';'); 
     for (var i = 0; i < cookies.length; i++) { 
      var cookie = jQuery.trim(cookies[i]); 
      if (cookie.substring(0, name.length + 1) === (name + '=')) { 
      cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); 
      break; 
      } 
     } 
     } 
     return cookieValue; 
    } 

    var csrftoken = getCookie('csrftoken'); 

    function csrfSafeMethod(method) { 
     return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); 
    } 
    $.ajaxSetup({ 
     beforeSend: function(xhr, settings) { 
      if (!csrfSafeMethod(settings.type) && !this.crossDomain) { 
       xhr.setRequestHeader("X-CSRFToken", csrftoken); 
      } 
     } 
    }); 
}; 
+0

AJAXコードを投稿してください。 –

+0

これでajaxコードが追加されました。 – DevB2F

+0

はコンソールにログを表示していますか? –

答えて

1

バックそれは、別の要求になります302 Foundステータスコードとして処理されるAJAXへHttpResponseRedirectオブジェクトを返しますリダイレクトされたリソースとコンテンツを取得します。あなたがコンテンツを入手したとしても、これは正しい方法ではないようです。

exam_resultsメソッドを使用して他の作業を行い、HttpResponseオブジェクトをrenderメソッドを使用して返すために必要なコンテキストを返すことができます。
dataを受け取ったら、受け取ったテンプレートにdocumentを置き換えることができます。

ソリューション

# views 

#this is the view where the jquery elements are being ordered by the user 
def inside_exam(request): 
    if request.method=='POST': 
     form = MyForm(request.POST) 
     if form.is_valid(): 
      #here I am able to retrieve the data from ajax and save it to a django model, code not shown here 

      context = exam_results(request) 

      return render(request, 'quizresults.html', context) 


# method to set the score for the exam 
# return context from this method 
def exam_results(request): 

    #here I set the score for the exam and set the context, code not shown here 

    # build context 
    return context 


# javascript 

    $.ajax({ 
     type: 'POST', 
     data: fd, 
     cache: false, 
     processData: false, 
     contentType: false 
    }).done(function(data) { 
     //The data from the quizresults.html template is printed out here, but that template is not shown, the template in the browser is still the insidequiz.html template. 
     console.log("the data"); 
     console.log(data); 

     // replace the page with the new template 
     var newDoc = document.open("text/html", "replace"); 
     newDoc.write(data); 
     newDoc.close(); 

     // update the url 
     window.history.pushState('', 'title', "newurl"); 
    }); 

参考:History API MDN

+0

これは機能しますが、コンソールで警告が表示されます。ドキュメントを介して、パーサーブロック、クロスサイト(つまり、別のeTLD + 1)スクリプト、https://code.jquery.com/jquery-1.12.4.jsが呼び出されます。書きます。このスクリプトのネットワークリクエストは、ネットワーク接続不良のために、このページまたは将来のページロードでブラウザによってブロックされる可能性があります。このページの読み込みでブロックされた場合、それは後続のコンソールメッセージで確認されます。詳細についてはhttps://www.chromestatus.com/feature/5718547946799104を参照してください。 – DevB2F

+0

もっと良い方法は、HTML全体の中で変化していると思われる部分だけを送ることです。テンプレート 'quizresults.html'をその方法で修正し、' $( 'elementToBeReplacedId').html(data) ''データ 'が' success'コールバックを返すようにします。 ' –

+0

あなたの助けに感謝します。ブラウザのURLは変更されません(newDoc.write(data)は実際にはリダイレクトではないため)。そこで、私はHTMLフォームを使用して終了し、Javascriptを使用してデータを追加し、フォームをURLに送信しました。 – DevB2F

0

私はアヤックスが、それはリダイレクトに来るとき、物事が複雑になることを考え出しました。私がやったことは、(隠されている)HTMLフォームを作成し、そのフォームをjavascriptを使ってURLに投稿することでした。 ajaxの必要はありません。

HTMLコード:

<form id="form1" action='{% url 'inside_exam' %}' method="post" style="display:none;"> 
    {% csrf_token %} 
</form> 

<p> <button type='submit' style="visibility" class="button button-long button-primary" onclick="sendData(this);">Send</button></p> 

javascriptのコード:

function sendData() { 
    var idsInOrder = $("#sortable").sortable('toArray'); 
    var form = document.getElementById('form1');  
    for(var i=0; i<idsInOrder.length; i++) { 
     j = i+1 
     var hiddenField = document.createElement("input"); 
     hiddenField.setAttribute("type", "hidden"); 
     hiddenField.setAttribute("name", 'a'+j); 
     hiddenField.setAttribute("value", idsInOrder[i]); 

     form.appendChild(hiddenField); 
    } 
    console.log("form is:"); 
    console.log(form); 

    form.submit(); 
}