Nayan
Nayan

Reputation: 48

How to update and save model's field in Django

Following is my code, Every time I click Like (or Dislike) link, both Dislike and Like are incremented. I am new to django, your help will be much appreciated. Thank you

Here is my models.py,

from django.db import models
from django.urls import reverse
# Create your models here.
class Movies(models.Model):
   Director=models.CharField(max_length=30)
   Cast_I=models.CharField(max_length=30)
   Cast_II=models.CharField(max_length=30)
   Name=models.TextField()
   ReleaseYear=models.IntegerField()
   ImdbRating=models.CharField(max_length=2)
   Genre=models.TextField(null=True)
   Language=models.CharField(max_length=20,null=True)
   Like=models.IntegerField()
   Dislike=models.IntegerField()
   def like_this_movie(self):
       self.Like+=1
       self.save()
       return reverse ('list',kwargs={})
   def dislike_this_movie(self):
       self.Dislike+=1
       self.save()
       return reverse ('list',kwargs={})

Here is the template,

{% block content %}
<p>
<a href="{{ object.like_this_movie }}">Like</a>
<a href="{{ object.dislike_this_movie }}">Dislike</a>
</p>
{% endblock %}

Here is my view class,

class MovieDetailView(DetailView):
    template_name='movie/detail.html'
    queryset=Movies.objects.all()

Upvotes: 0

Views: 181

Answers (4)

Nayan
Nayan

Reputation: 48

Now I have resolved this by using jQquery AJAX, like_this_movie and dislike_this_movie function returns json value to ajax request. Now page doesn't reload every time I hit like or dislike button. Thank you guys for your valuable answer. views.py,

def like_this_movie(request,key):
    obj=Movies.objects.get(pk=key)
    obj.Like+=1
    obj.save()
    return JsonResponse({'success':True,'content':'Like','Like':obj.Like})
def dislike_this_movie(request,key):
    obj=Movies.objects.get(pk=key)
    obj.Dislike+=1
    obj.save()
    return JsonResponse({'success':True,'content':'Dislike','Dislike':obj.Dislike})

urls.py,

urlpatterns=[
    path('<int:key>/like',like_this_movie,name='like'),
    path('<int:key>/dislike',dislike_this_movie,name='dislike')
]

detail.js

  document.addEventListener('DOMContentLoaded',()=>{
    document.querySelector('#likebtn').onclick=()=>{
      const request=new XMLHttpRequest;
      request.open('GET','like',true);
      console.log(request);
      request.onload=()=>{
        const data = JSON.parse(request.responseText);
        if ((data.success)&&(data.content=='Like')){
          totalLike=data.Like;
          likespan=document.querySelector('#likespan');
          likespan.innerHTML=totalLike;
          likebtn=document.querySelector('#likebtn');
          likebtn.disabled = true;
          dislikebtn.disabled=true;
        }
      }
      request.send();
      return false;
    }
    document.querySelector('#dislikebtn').onclick=()=>{
      const request=new XMLHttpRequest;
      request.open('GET','dislike',true);
      request.onload=()=>{
        const data = JSON.parse(request.responseText);
        if ((data.success)&&(data.content=='Dislike')){
          totalDislike=data.Dislike;
          dislikespan=document.querySelector('#dislikespan');
          dislikespan.innerHTML=totalDislike;
          dislikebtn=document.querySelector('#dislikebtn');
          dislikebtn.disabled = true;
          likebtn.disabled=true;
        }
      }
      request.send();
      return false;
    }
  })

detail.html,

    <h4>
        <span id="likespan">{{object.Like}}</span>
        <button id="likebtn" type="submit" class="btn btn-primary">Like</button>
        <span id="dislikespan">{{object.Dislike}}</span>
        <button id="dislikebtn" type="submit" class="btn btn-primary">Dislike</button>
    </h4>

Upvotes: 0

Nayan
Nayan

Reputation: 48

I have resolved my bug by adding those like_this_movie and dislike_this_movie function to my views.py and updating my urls.py and template. Thank you guys for your valuable answer. views.py,

def like_this_movie(request,key):
    obj=Movies.objects.get(pk=key)
    obj.Like+=1
    obj.save()
    return redirect('/movie/list')
def dislike_this_movie(request,key):
    obj=Movies.objects.get(pk=key)
    obj.Dislike+=1
    obj.save()
    return redirect('/movie/list')

urls.py,

urlpatterns=[
    path('list/<int:key>/like',like_this_movie,name='like'),
    path('list/<int:key>/dislike',dislike_this_movie,name='dislike')
]

template,

<a href="{% url 'like' object.pk %}">Like</a>
<a href="{% url 'dislike' object.pk %}">Dislike</a>

Upvotes: 0

Farouk T.
Farouk T.

Reputation: 51

The problem is that each time you load the page both values are incremented because you call both functions in each call. This link will help you on how do it => How to make user to Like/Dislike post only for once in Django?

Upvotes: 1

Felix Ekl&#246;f
Felix Ekl&#246;f

Reputation: 3720

The templates in Django don't work like that, everything you put inside {{ }} is rendered on the server and then the page is sent to the client, so it is not possible to run a function like that.

You would have to do something like an AJAX request to another page which runs like_this_movie and takes the Movies id as a parameter. To send to AJAX request you can use Javascript with jQuery.

Upvotes: 1

Related Questions