skip to Main Content

I have been working on a like/unlike function on my django project in which a user can like like a post and if so the user can dislike it like in instagram. Now to finish with this part of the project I need to make the not refresh the page when a like or unlike button is pressed but the problem is that I am very very new to ajax. How can I acomplish this?

models.py

class Post(models.Model):
    text = models.CharField(max_length=200)
    user = models.ForeignKey(User, related_name='imageuser', on_delete=models.CASCADE, default='username')
    liked = models.ManyToManyField(User, default=None, blank=True, related_name='liked')
    updated = models.DateTimeField(auto_now=True)
    created =models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return str(self.text)

    def get_absolute_url(self):
        return reverse('comments', args=[self.pk])
    
LIKE_CHOICES = (
    ('Like', 'Like'),
    ('Unlike', 'Unlike'),
)

class Like(models.Model):
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    post = models.ForeignKey(Post, on_delete=models.CASCADE)
    value = models.CharField(choices=LIKE_CHOICES, default='Like', max_length=10)

    def __str__(self):
        return str(self.post)

views.py

def like_post(request):
    user = request.user
    if request.method == 'POST':
        post_id = request.POST.get('post_id')
        post_obj = Post.objects.get(id=post_id)

        if user in post_obj.liked.all():
            post_obj.liked.remove(user)
        else:
            post_obj.liked.add(user)

        like, created = Like.objects.get_or_create(author=user, post_id=post_id)

        if not created:
            if like.value == 'Like':
                like.value == 'Unlike'
            else:
                like.value = 'Like'
        
        like.save()
    return redirect('home')

def home(request):
    contents = Post.objects.all()

    context = {
        "contents": contents,
    }
    print("nice2")
    return render(request, 'home.html', context)

urls.py

urlpatterns = [
    path('', views.home, name='home'),
    path('like/', views.like_post, name="like-post"),
]

home.html

<form action="{% url 'like-post' %}" method="POST">
  {% csrf_token %}
  <input type='hidden' name="post_id" value="{{ content.id }}">
  {% if user not in content.liked.all %}
    <button type="submit">Like</button>
  {% else %}
    <button type="submit">Unlike</button>
  {% endif %}
</form>
<strong>{{ content.liked.all.count }}</strong>

2

Answers


  1. To avoid updating the page, you can set the button on your html as:

     <button type='button'>submit</button>
    

    Instead of using submit, you’ll have to add an event listener to the button or a function associated with the onclick so you can call the ajax to handle this request on the background.

    You can also achieve that by providing a null action for you form, by using:

    <form action="javascript:void(0);" method="POST">
    

    Take a look at this tutorial:
    https://simpleisbetterthancomplex.com/tutorial/2016/08/29/how-to-work-with-ajax-request-with-django.html

    Login or Signup to reply.
  2. This is related to the default html behavior of a button with type=submit inside a form tag. By default, if you click in the button with type submit, it tries to send your data and reload your page. You can just change the type of the button and let your javascript code deal with the button behavior. On each of your buttons, add:

    <button id="like-button" type="button">Like</button>
    

    For the JavaScript code, just add to your tag or separate js file:

    window.addEventListener('DOMContentLoaded', (event) => {
        let likeButton = document.querySelector(#like-button);
        likeButton.addEventListener('click', () => {
              your code when like button is clicked
        }
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search