Django and Jquery $.post function

5.2k Views Asked by At

I am having trouble using the $.post() function with my views. I get no errors. I just get nothing from the jscript. It is either not reaching my view, or my view isn't calling my template.

my html snippet is

<textarea rows="4" cols"30" id="id_new_list" placeholder="Enter a gene list"></textarea>
<button type="button" onclick="parseList();">submit list</button>

<table id="id_list_table">
  <tr><td>{{ new_item_text }}</td></tr>
</table>

my jscript is:

var main = function(){   
    $('button').click(function(){
       var data = document.getElementById("id_new_list").value;
       $.post('lists/new',{item_text:data});   });
};

$(document).ready(main);

my view is:

def home_page(request):   
    return render(request,'lists/home.html',{
        'new_item_text':request.POST.get('item_text',''),
    })  

def new_list(request):   
    data = request.POST.get('item_text','')  
    return render(request,'home.html',{
        'new_item_text': data,
    })

my url files:

urlpatterns = patterns('',
    url(r'^$', 'lists.views.home_page', name='home'),
    url(r'^lists/', include('lists.urls')),
)

urlpatterns = patterns('',
    url(r'^new$','lists.views.new_list',name='new_list'),
    )  

I am not even getting the post to call my view I dont't think. My textarea and button were with form tags but I removed them and assumed it may be the csrf that was the issue.

2

There are 2 best solutions below

1
On BEST ANSWER

While the answer posted by shellbye may solve your problem, it also makes you vulnerable to CSRF attacks. Use csrf_exempt only if you know what you're doing. Do read Django docs on CSRF protection to know more.

Alternative to other answer

You need to pass the CSRF token with every POST request.

HTML

<form ...>
    <!-- Set the CSRF token in the template -->
    {% csrf_token %}
    <textarea ... ></textarea>
</form>

The {% csrf_token %} template tag will generate a hidden input field in your template with a random value, like this:

<input type="hidden" name="csrfmiddlewaretoken" value="Sdf67Ghbsdf786afdsdf">

So, now you need to access this value and pass in the $.post parameters.

JS/jQuery

var main = function(){   
    $('button').click(function(){

        // get the value of CSRF token
        var CSRFtoken = $('input[name=csrfmiddlewaretoken]').val();

        var data = document.getElementById("id_new_list").value;

       $.post('lists/new', { 
           item_text: data,
           csrfmiddlewaretoken: CSRFtoken
       });
    });
};

That's it. Make sure in the $.post parameters you don't name CSRF token other than csrfmiddlewaretoken because Django will access it only by this name.

Yet another alternative

In case you have to make many different AJAX post requests, you will need to pass CSRF token to each one of them. To save you that hassle, here's a good approach to do this once and for all.

0
On

You have a typo where cols"30" should be cols="30".

And you need @csrf_exempt() above your new_list like this:

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def new_list(request):   
data = request.POST.get('item_text','')  
    return render(request,'home.html',{
        'new_item_text': data,
    })