How to handle AJAX POST request in Django

Viewed 1354

I have a sort of twitter like button function in my app such that, when the button is clicked, it triggers an AJAX call and performs the action specified in the views. However, when i click the button, it does not perform action in views. The code reaches the 'like view' but does not execute anything after 'if request.POST:'. Please help.

Menu.html

<form action="{% url 'like'%}" id="plt_{{menu.id}}" data-id="{{menu.id}}" method="post">
        {%csrf_token%}
   <input name="menu_id" type="hidden" value="{{ menu.id }}">
    <div class="like-button" id="btn_{{menu.id}}"></div>
</form>
<script>
     $('.like-button').on('click', function () {
         var id = $(this).attr('id');
         id = id.replace('btn_','');

         $(this).toggleClass('animate').promise().done(function () {
            var link = $("#plt_"+id).attr('action')
                $.ajax({
                    type: 'POST',
                    url: link,
                    headers: {'X-CSRFToken': '{{ csrf_token }}'},
                })
                });
    });

 </script>

Views.py

def like(request):
    print('reached') //this prints
    if request.POST:
     menu = Menu.objects.get(pk=request.POST.get('menu_id'))
     //execute code to like
     return HTTPResponse('')

2 Answers

Maybe you want to check

if request.is_ajax() and request.method== "POST":

request.POST is a dict .Empty here because body is empty in your request.

Empty dicts are treated like False by python like

if {}:
    print("Hello World") 

Above won't print anything

But below works

if {"hi" : "there"}:
    print("Hello World")

And docs suggests this check is wrong if request.POST:

It’s possible that a request can come in via POST with an empty POST dictionary – if, say, a form is requested via the POST HTTP method but does not include form data. Therefore, you shouldn’t use if request.POST to check for use of the POST method; instead, use if request.method == "POST" (see HttpRequest.method).

It is fairly simple, use serialize() of jquery. Serialize function will take all the values from the form, even csrftokenmiddleware which is hidden input type. So, doing so you will be able to handle post request successfully. Use sthg like this:

<script>
     $('.like-button').on('click', function () {
         var id = $(this).attr('id');
         id = id.replace('btn_','');

         $(this).toggleClass('animate').promise().done(function () {
            var link = $("#plt_"+id).attr('action');
            var data = $("#plt_"+id).serialize();   // It will serialize all form data
                $.ajax({
                    type: 'POST',
                    url: link,
                    data: data
                });
         });
    });

 </script>

In views.py do as you do for other request. serialize()

Related