Reputation: 15
I am very new to jQuery and trying to make a simple app which allows people to like photos using Ajax call. Here are the relevant parts:
photo.html:
{% if pic %}
<img class="pic" src="/static/assets/{{pic}}" />
<br />
{% csrf_token %}
<input type="button" id="like" name="like" value="Like" />
<p id="likes"> </p> people liked this
{% endif %}
views.py
def like_photo(request, pic_id):
if request.method == 'POST':
if pic_id:
uid = request.user.id
p=UserPic.objects.get(id=pic_id)
if Liker.objects.filter(user=uid, pic=pic_id):
p.likes -=1
p.save()
Liker.objects.filter(user= uid, pic=pic_id).delete()
else:
p.likes +=1
p.save()
newliker = Liker(user= uid, pic=pic_id)
newliker.save()
args = {}
args.update(csrf(request))
args['likes']= p.likes
return render_to_response('photo.html', args)
like.js
$(function(){
$('#like').click(function() {
var $this = $(this);
var post_id = this.id;
$.ajax({
type: "POST",
url: "'/photo/like/'+ post_id",
data: {
'csrfmiddlewaretoken' : $("input[name=csrfmiddlewaretoken]").val()
},
success: likeSuccess,
dataType: 'html'
});
});
});
function likeSuccess(data, textStatus, jqXHR)
{
$('#likes').html(data);
}
I can see in Firebug that jQuery and like.js are loaded on the page but clicking the like button does not have any effect according to Firebug's XHR.
The app works perfectly fine without AJAX call, that is, when I use a simple anchor in the template:
<p><a href="/photo/like/{{pic.id}}">Like</a></p>
Upvotes: 0
Views: 366
Reputation: 15
Ok I manged to get in work like this:
photo.html:
{% if pic %}
<script>
$(document).ready(function(){
$('#like').click(function() {
var $this = $(this);
var post_id = {{pic.id}};
$.ajax({
type: "POST",
url: "/photo/like/" + post_id ,
data: {
'pic_id': post_id,
'csrfmiddlewaretoken' : $("input[name=csrfmiddlewaretoken]").val()
},
success: likeSuccess,
dataType: 'html'
});
});
});
function likeSuccess(data, textStatus, jqXHR)
{
$('#likes').html(data);
}
</script>
<img class="pic" src="/static/assets/{{pic}}" />
<br />
{% csrf_token %}
<input type="button" id="like" name="like" value="Like" />
<p id="likes"> {{pic.likes}} liked this </p>
{% endif %}
views.py
def like_photo(request, pic_id):
if request.method == 'POST':
if pic_id:
uid = request.user.id
p=UserPic.objects.get(id=pic_id)
#if UserPic.objects.filter(liked_by__user__contains=uid):
if Liker.objects.filter(user=uid, pic=pic_id):
#return HttpResponse('You have already liked!')
p.likes -=1
p.save()
Liker.objects.filter(user= uid, pic=pic_id).delete()
else:
p.likes +=1
p.save()
newliker = Liker(user= uid, pic=pic_id)
newliker.save()
args = {}
args.update(csrf(request))
args['likes'] = p.likes
return render_to_response('userpics/likes.html', args)
also needed to create a specific html for ajax call:
likes.html
{% if likes > 0 %}
{{likes}} liked this
{% else %}
crap
{% endif %}
Not sure if it is the best way but it works. I wish I could use a more elegant json to return the likes digit and get rid of the likes.html but could not figure out how to do so.
Also, for some strange reason the script does not work when I import it externally at base.html:
<script src="{% static "assets/js/likes.js" %}"></script>
though firebug says that it is loaded on the page.
Your suggestions to improve the answer are welcomed.
Upvotes: 0
Reputation: 6071
there was a small (but significant!) bug in your code
"'/photo/like/'+ post_id"
is incorrect, you want "/photo/like/" + post_id
. notice it isn't all surrounded by quotes
Upvotes: 1