'Update ManyToManyField by calling view via ajax("Like" button)
Not sure if this is more of a javascript question or a django question so please forgive me if it is in the wrong spot. I am trying to update a ManyToMany field representing "likes" on an image by calling a view via ajax. The "like" portion is working, the "unlike" portion is not.
I have an Image model with a users_like field:
class Image(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name = 'images_created', on_delete=models.CASCADE)
users_like = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name="images_liked", blank = True)
# etc
The view:
def image_like(request):
image_id = request.POST.get('id')
action = request.POST.get('action')
if image_id and action:
try:
image = Image.objects.get(id = image_id)
if action == 'like':
image.users_like.add(request.user)
else:
images.users_like.remove(request.user)
return JsonResponse({'status': 'ok'})
except:
pass
return JsonResponse({'status': 'ko'})
Url:
path('like/', views.image_like, name = 'like'),
html/js:
<a href="#" data-id="{{ image.id }}" data-action="{% if request.user in users_like %}un{% endif %}like" class="like button">
{% if request.user not in users_like %}
Like
{% else %}
Unlike
{% endif %}
</a>
<!-- other html, skipping down to the jQuery-->
{% block domready %}
$('a.like').click(function(e){
e.preventDefault();
$.post('{% url "images:like" %}',
{
id: $(this).data('id'),
action: $(this).data('action')
},
function(data){
if (data['status'] == 'ok')
{
var previous_action = $('a.like').data('action');
// toggle data-action
$('a.like').data('action', previous_action == 'like' ? 'unlike' : 'like');
// toggle link text
$('a.like').text(previous_action == 'like' ? 'Unlike' : 'Like');
// update total likes
var previous_likes = parseInt($('span.count .total').text());
$('span.count .total').text(previous_action == 'like' ? previous_likes + 1 : previous_likes - 1);
}
}
);
});
{% endblock %}
This code successfully allows a user to 'like' a post and the link subsequently changes to <a href="#" data-id="18" data-action="unlike" class="like button">Unlike </a>, so both the data-action and text are updating properly, but then if I click it again, it doesn't "unlike" the image. Not sure what is going here, as when the data-action attribute is equal to "unlike", the
else:
images.users_like.remove(request.user)
portion of the view should go into effect, it seems like the view is not being called again but I am not sure. Thanks for any help.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
