i'm making a like button in Django with a JSON code but i when I click the like button it doesn't increment the number of likes in this product or pass the like (as this hunter liked this product).Do I need to make a separate class for like in models.py, if so what should be in it. Or is it that the slug isn't set up the right way. In the urls.py and models.py I'm showing all the code, in views.py only the method of the like button and the imports, and in detail.html only the HTML tag's for the like button and the JSON script. I'm working with : Django Version: 2.2.9 Python Version: 3.7.4 .
The models.py in the app "products":
from django.db import models
from django.contrib.auth.models import User
from django.template.defaultfilters import slugify
from django.urls import reverse
class Product(models.Model):
title = models.CharField(max_length = 80)
pub_date = models.DateTimeField()
body = models.TextField()
url = models.TextField()
image = models.ImageField(upload_to = 'images/')
icon = models.ImageField(upload_to = 'icon/')
votes_total = models.IntegerField(default=1)
slug = models.SlugField(null=False, unique=True)
likes = models.ManyToManyField(User, blank=True, related_name='likes')
hunter = models.ForeignKey(User, on_delete = models.CASCADE)
def __str__(self):
return self.title
def summary(self):
return self.body[:100] + "..."
def pub_date_pretty(self):
return self.pub_date.strftime("%b %e %Y")
def save(self, *args, **kwargs):
#if not self.slug:
#self.slug = slugify(self.title)
if not self.slug:
slug = slugify(self.title)
while True:
try:
product = Product.objects.get(slug=slug)
if article == self:
self.slug = slug
break
else:
slug = slug + '-'
except:
self.slug = slug
break
return super(Product, self).save(*args, **kwargs)
@property
def total_likes(self):
return self.likes.count()
The views.py in the app "products":
from django.http import HttpResponse
try:
from django.utils import simplejson as json
except ImportError:
import json
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required
from .models import Product
from django.contrib.auth.models import User
from django.utils import timezone
from django.views.decorators.http import require_POST
def home(request):
products = Product.objects
return render(request, 'products/home.html', {'products':products})
@login_required(login_url = '/accounts/signup')
def create(request):
if request.method == 'POST':
if request.POST['title'] and request.POST['body'] and request.POST['url'] and request.FILES['icon'] and request.FILES['image']:
product = Product()
product.title = request.POST['title']
product.body = request.POST['body']
if request.POST['url'].startswith('http://') or request.POST['url'].startswith('https://'):
product.url = request.POST['url']
else:
product.url = 'http://' + request.POST['url']
product.icon = request.FILES['icon']
product.image = request.FILES['image']
product.pub_date = timezone.datetime.now()
product.hunter = request.user
product.save()
return redirect('/products/' + str(product.id))
else:
return render(request, 'products/create.html', {'error':'All fields are required.'})
else:
return render(request, 'products/create.html')
def detail(request, product_id):
detail_product = get_object_or_404(Product, pk = product_id)
return render(request, 'products/detail.html', {'product' : detail_product})
@login_required(login_url = '/accounts/signup')
@require_POST
def like(request):
if request.method == 'POST':
hunter = request.user
slug = request.POST.get('slug', None)
product = get_object_or_404(Product, slug = slug)
if product.likes.filter(hunter_id = hunter.id).exists():
# user has already liked this company
# remove like/user
product.likes.remove(hunter)
message = 'You disliked this'
product.save()
else:
# add a new like for a company
product.likes.add(hunter)
message = 'You liked this'
product.save()
ctx = {'likes_count': product.total_likes, 'message': message}
# use mimetype instead of content_type if django < 5
return HttpResponse(json.dumps(ctx), content_type='application/json')
The urls.py in products app:
from django.urls import path, include
from . import views
urlpatterns = [
path('create', views.create, name = 'create'),
path('<int:product_id>/', views.detail, name = 'detail'),
path('<int:product_id>/upvote', views.upvote, name = 'upvote'),
path('user/<int:fk>', views.hunterhunts, name = 'hunterhunts'),
path('<slug:slug>', views.like, name='like'),
]
The HTML file detail.html in the "products" app :
<input type="button" id="like" name="{{ product.slug }}" value="Like" />
<script>
$('#like').click(function() {
$.ajax({
type: "POST",
url: "{% url 'like' product.slug %}",
data: {
'slug': $(this).attr('name'),
'csrfmiddlewaretoken': '{{ csrf_token }}'
},
dataType: "json",
success: function(response) {
alert(response.message);
alert('Product likes count is now ' + response.likes_count);
},
error: function(rs, e) {
alert(rs.responseText);
}
});
});
</script>
Any idea what should be corrected or added for the like button to work.
Please be explicit if you can!!!