0

I am trying to build a ajax powered like button, but the ajax code is not working.

views.py
def like_button(request,postid):
    postresult=get_object_or_404(post,id=postid)
    if postresult.user_like.filter(id=request.user.id).exists():
        postresult.user_like.remove(request.user)
    else:
        postresult.user_like.add(request.user)
    noresdat=postresult.totallikes
    response_data_to_dump={'success': True,'likes':noresdat}
    data = json.dumps(response_data_to_dump)
    return HttpResponse(data, content_type='application/json')

while template is as follows:-

{% for p in result %}
    <div class="SpriteContainer"> 
      <a class="postlike" href="/like/{{ p.id }}"><img src="{%static "/images/icons/heart.png" %}"/></a>
      <p class="nolike" style="display: inline-block;">{{ p.totallikes }}</p></div>
    {% endfor %}
<script>
    var csrftoken = $("[name=csrfmiddlewaretoken]").val();
    $(".postlike").click(function(e){
      e.preventDefault();
      var $this = $(this);
      var url = $(this).data("action");
      $.post(url, function(response){
      if(response && response.success==true)
      $this.next(".nolike").text(response.likes);
  });
});

Gagan
  • 367
  • 1
  • 4
  • 18
  • You need to set csrf_token in request header. This may help you, https://stackoverflow.com/a/5107878/10853347 – shafik Jan 06 '19 at 13:00
  • @ShafikurRahman already tried that solution but on clicking after implementing it gives json not the page – Gagan Jan 06 '19 at 13:03

2 Answers2

0

The CSRF middleware and template tag provides easy-to-use protection against Cross Site Request Forgeries.(Django).

And The CSRF middleware is activated by default in the MIDDLEWARE setting. So either you will have to provide csrf token or you will have to exempt that view from CSRF. Views are based on classes or functions. Since you are using function based views, you can take advantage of [csrf_exempt].1

from django.views.decorators.csrf import csrf_exempt,
    @csrf_exempt
    def like_button(request,postid):
AjayShelar
  • 462
  • 4
  • 6
0

Right now, you are not sending your token value with your request.

You should be sending csrf_token in your post request data so that django can check against its value.

Try this-

{% for p in result %}
    <div class="SpriteContainer"> 
      <a class="postlike" href="/like/{{ p.id }}"><img src="{%static "/images/icons/heart.png" %}"/></a>
      <p class="nolike" style="display: inline-block;">{{ p.totallikes }}</p></div>
    {% endfor %}
{% csrf_token %} <!-- getting csrf token value in html page -->


<script>
    var csrftoken = $("[name=csrfmiddlewaretoken]").val();
    $(".postlike").click(function(e){
      e.preventDefault();
      var $this = $(this);
      var url = $(this).data("action");
      $.post(url, {csrfmiddlewaretoken: csrftoken}, function(response){ // send csrf in post request data
      if(response && response.success==true)
      $this.next(".nolike").text(response.likes);
  });
});

Using csrf_exempt is usually considered a bad idea and this work around should be used carefully as it exposes your website to potential security risks.

aquaman
  • 1,523
  • 5
  • 20
  • 39