Note that there are some explanatory texts on larger screens.

plurals
  1. PODjango 1.5 CSRF Ajax
    primarykey
    data
    text
    <p>I'm trying to create a web app that makes Ajax calls when certain buttons are clicked, updating data in my models and displaying the updated data. Here is my template:</p> <pre><code>&lt;html&gt; &lt;head&gt; &lt;script src="http://code.jquery.com/jquery-1.9.1.min.js"&gt;&lt;/script&gt; &lt;script src="{{ STATIC_URL }}/workout1.js"&gt;&lt;/script&gt; &lt;/head&gt; &lt;body&gt; &lt;span id="squats"&gt;Squats: {{ user.weekOne.squats }} done.&lt;br/&gt;&lt;/span&gt; &lt;span id="lunges"&gt;Lunges: {{ user.weekOne.lunges }} done.&lt;br /&gt;&lt;/span&gt; &lt;span id="stairDays"&gt;Stair Days: {{ user.weekOne.stairDaysCount }}&lt;br/&gt;&lt;/span&gt; &lt;span id="skipStairs"&gt;Skip Stairs: {{ user.weekOne.skipStairs }}&lt;br /&gt;&lt;/span&gt; &lt;form&gt; {% csrf_token %} &lt;input type="text" name="squats" id="squatsVal" value="Squats" /&gt; &lt;input type="submit" id="submitSquats" value="Add Squats"/&gt;&lt;br /&gt; &lt;/form&gt; &lt;form&gt; &lt;input type="text" name="lunges" value="Lunges" /&gt; &lt;input type="submit" value="Add Lunges" /&gt;&lt;br /&gt; &lt;/form&gt; &lt;form&gt; &lt;input type="submit" value="Stairs skipped."&gt;&lt;br /&gt; &lt;/form&gt; &lt;/body&gt; &lt;/html&gt; </code></pre> <p>I use Django's <a href="https://docs.djangoproject.com/en/dev/ref/contrib/csrf/" rel="nofollow">suggested code</a> for dealing with Ajax and CSRF. Here is my resultant jQuery: </p> <p>$(document).ready(function() {</p> <pre><code>// Boilerplate for handling CSRF, from Django's website function getCookie(name) { var cookieValue = null; if (document.cookie &amp;&amp; document.cookie != '') { var cookies = document.cookie.split(';'); for (var i = 0; i &lt; cookies.length; i++) { var cookie = jQuery.trim(cookies[i]); // Does this cookie string begin with the name we want? if (cookie.substring(0, name.length + 1) == (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; }; var csrftoken = getCookie('csrftoken'); $.ajaxSetup({ crossDomain: false, // obviates need for sameOrigin test beforeSend: function(xhr, settings) { if (!csrfSafeMethod(settings.type)) { xhr.setRequestHeader("X-CSRFToken", csrftoken); } } }); // the actual Ajax $("#submitSquats").click(function() { var exercise = "squats"; var amount = $('#squats').val(); var data = {'exercise': exercise, 'amount': amount}; $.ajax({ type:"POST", url:"submitWorkout1", data: data, success: function() { $('#squats').html('&lt;span&gt;Success&lt;/span&gt;'); } }); return false; }); </code></pre> <p>});</p> <p>Finally, here is the view that handles the incoming Ajax request and returns a response for the Ajax to work with: </p> <pre><code>def submitWorkout1(request): exercise = request.POST['exercise'] amount = request.POST['amount'] user = UserProfile.objects.get(user=request.user) exercise, amount = user.WeekOne.updateExercise(exercise, amount) return HttpResponse(simplejson.dumps({'result': 'success', exercise: amount})) </code></pre> <p>Unfortunately, when I try to click on the Submit Squats button and run the jQuery, I get a <code>CSRF Token Missing or Incorrect</code> error message. Moreover, if I use a @csrf_exempt identifier on top of my view for testing purposes, I get this error: </p> <pre><code>"Key 'exercise' not found in &lt;QueryDict: {u'undefined': [u'', u'']}&gt;" </code></pre> <p>So even if I were to fix the CSRF problem, it appears there is something else wrong with my Ajax code. But I want to fix both problems. Help! </p> <p>Updated code (see catherine's post below): </p> <p>HTML:</p> <pre><code>&lt;body&gt; &lt;span id="squats"&gt;Squats: {{ user.weekOne.squats }} done.&lt;br/&gt;&lt;/span&gt; &lt;span id="lunges"&gt;Lunges: {{ user.weekOne.lunges }} done.&lt;br /&gt;&lt;/span&gt; &lt;span id="stairDays"&gt;Stair Days: {{ user.weekOne.stairDaysCount }}&lt;br/&gt;&lt;/span&gt; &lt;span id="skipStairs"&gt;Skip Stairs: {{ user.weekOne.skipStairs }}&lt;br /&gt;&lt;/span&gt; &lt;form method="POST" action="{% url workout_game_app.views.submitWorkout1 %}"&gt; {% csrf_token %} &lt;input type="text" name="squats" id="squatsVal" value="Squats" /&gt; &lt;input type="submit" id="submitSquats" value="Add Squats"/&gt;&lt;br /&gt; &lt;/form&gt; &lt;/body&gt; </code></pre> <p>jQuery:</p> <pre><code>$(document).ready(function() { $("#submitSquats").click(function() { var exercise = "squats"; var amount = $('#squats').val(); $.ajax({ type:"POST", url:"/workout_game_app/workouts/submitWorkout1/", data: {'exercise': exercise, 'amount:': amount, 'csrfmiddlewaretoken': '{{csrf_token}}'}, contentType: "application/json;charset=utf-8", dataType: "json", success: function() { $('#squats').html('&lt;span&gt;Success&lt;/span&gt;'); } }); return false; }); }); </code></pre> <p>view:</p> <pre><code>def submitWorkout1(request): if request.method == 'POST': exercise = request.POST['exercise'] amount = request.POST['amount'] user = UserProfile.objects.get(user=request.user) exercise, amount = user.WeekOne.updateExercise(exercise, amount) data = simplejson.dumps({ 'result': 'success', 'exercise': exercise, 'amount': amount }, indent=4) return HttpResponse(data, mimetype="application/javascript") </code></pre> <p>URL:</p> <pre><code>urlpatterns = patterns('', url(r'^$', 'workout_game_app.views.index'), url(r'^signup$/', 'workout_game_app.views.signup'), url(r'^login$/', 'workout_game_app.views.login_view'), url(r'^logout/$', 'workout_game_app.views.logout_view'), url(r'^workouts/workout1/$', 'workout_game_app.views.workout1'), url(r'^workouts/submitWorkout1/$', 'workout_game_app.views.submitWorkout1'), </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload