-1

I have been working on a like system in which a user can like a post and unlike if it is already liked by that user, very similar to instagram. So after finishing with this system I realized that the page is reloading everytime a button is pressed and I dont want that to happen, after some investigation I concluded that this can be done using json or jquery but the problem is that I haven't really used that because I am focusing exclusively on learning django for now. How would be the code to make the page dont refresh when the buttons are pressed?

models.py

class Post(models.Model):
    text = models.CharField(max_length=200)
    video = models.FileField(upload_to='clips', null=True, blank=True)
    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)

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>

1 Answers1

0

You can use an AJAX request for this. You can read documentation about how to use AJAX with django, e.g. here is a really good answer on SO: https://stackoverflow.com/a/20307569/13290801

Just because you are focussing on learning django doesn't mean you can ignore other languages, because what you need to use is dependent on what you want to achieve.

The basic jquery setup will be something like this:

$(document).ready(function(){
$(".like").click(function() {
  var contentpk = $(this).data('contentpk');
    $.ajax({
        url: "//", //your like_post url should go here, you can use the variable created above (contentpk) if that is in your url
        success: function(result) {
        }});
      });
    });

And your html would need to be altered somewhat:

{% if user not in content.liked.all %}
  <a class="btn like" href="javascript:" data-content="{{content.pk}}">Like</a>
{% else %}
  <a class="btn like" href="javascript:" data-content="{{content.pk}}">Unlike</a>
{% endif %}

And this is also assuming that you already have the jquery cdn script in your html.

MeL
  • 1,269
  • 3
  • 12
  • 30
  • Thanks! I will try that tomorrow morning and I will let you know what happened, I will try to learn more languages as you suggested starting with jquery and JavaScript which seems very interesting –  Jul 25 '20 at 03:27
  • Hey Mel! I just tried you code and there is no error popping up but the like button is getting no job done, it is not liking the post because it is not counting the like or changing the text to unlike –  Jul 26 '20 at 01:58
  • Also I used `{% url 'like_post' %}` for the url part of the ajax. I think the error is on the href from the html or in the url but I dont know how to fix it. –  Jul 26 '20 at 02:00
  • Maybe the error might be on the data-content because I dont use pk before on the backend –  Jul 26 '20 at 02:27