1

I'm doing a small project in Django, in that I thought of adding a favorite button in one of the pages so that on clicking on that button it has to return the model object and it has to be stored in another database for the reference, but it's not happening Here is my home/bookdetails.html

<!DOCTYPE html>

{% extends 'home/Base.html' %}

{% block title %} Book Details {% endblock %}
{% load staticfiles %}

<link rel="stylesheet" href="{{ STATIC_URL }}/home/css/heart.css">
<script src="{% static 'js/heart.css' %}"></script>
<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
<script src="{% static 'js/app.js' %}"></script>

{% block body %}

{% if error_message %}<p><strong> {{ error_message }} </strong></p>{% endif %}
<script type="text/javascript">
$(document).ready(function(){
$("#sub").click(function(event) {
 var userbooks = '{{ userbooks }}';
 $.ajax({
            type: "GET",
            url: "{% url 'home:favoriteAjax' %}"
            data:{userbbooks:userbooks}
            datatype:'json'
            success: function() {
            alert("successfully added to favorites")
            }
        }
        });
});
});

</script>
<p>Book name:{{ userbooks.book_name }}</p><br>
<p>Book author:{{ userbooks.book_author }}</p><br>
<p>Book genre:{{ userbooks.book_genre }}</p><br>
<p>Book ISBN:{{ userbooks.book_ISBN }}</p><br>
<button type="submit" id="sub" onclick="changeText()">Favourite</button>

{% endblock %}

my urls.py:

from django.urls import path
from . import views
app_name='home'
urlpatterns=[
    path('',views.HomeView,name='home'),
    path('addBooks/',views.addBooks,name='addBooks'),
    path('myBooks/',views.BooksView.as_view(),name='myBooks'),
    path('<int:pk>/', views.BookDetailsView.as_view(), name='myBooks'),
    path('search/', views.SearchedBooks.as_view(), name='searchedBooks'),
    path('favorite_ajax/', views.favorite_ajax, name='favoriteAjax'),
    ]

my models.py:

from django.db import models
from django.contrib.auth.models import User
class UserBooks(models.Model):
    user_id = models.ForeignKey(User,on_delete=models.CASCADE,null=True)
    username = models.CharField(max_length=200)
    book_name = models.CharField(max_length=200)
    book_author = models.CharField(max_length=200)
    book_ISBN=models.CharField(max_length=200)
    book_genre = models.CharField(max_length=200)
    book_status=models.BooleanField(default=False)
    class Meta:
        unique_together = (("username", "book_ISBN"),)
    def __str__(self):
        return self.book_name

class FavBooks(models.Model):
    user_id = models.ForeignKey(User,on_delete=models.CASCADE,null=True)
    book_id= models.ForeignKey(UserBooks,on_delete=models.CASCADE,null=True)
    class Meta:
        unique_together = (("user_id", "book_id"),)

my views.py:

def favorite_ajax(request):
    if(request.method=='GET'):
        book=request.GET['userbooks']
        fav=FavBooks()
        fav.book_id=book
        fav.user_id=request.user
        fav.save()
    return HttpResponse("done")

I want to take the userbooks model object from the bookdetails.html through ajax call and want to store that reference in the FavBooks model. How could I make it happen? Thanks!

Abijith Mg
  • 2,647
  • 21
  • 35

1 Answers1

4

This is the right way of doing it:

html:

 <form id="form_id" method='post'>{% csrf_token %}
     <button type="submit">Favourite</button>
 </form>

jQuery:

 $("#form_id").on('submit', function(event) {
       event.preventDefault(); 
       var userbooks = '{{ userbooks }}';
       $.ajax({
           type: "POST",
           url: "{% url 'home:favoriteAjax' %}",
           data:{
                 userbooks:userbooks, 
                'csrfmiddlewaretoken': $('input[name=csrfmiddlewaretoken]').val()
           },
           datatype:'json',
           success: function(data) {
             if (data['success'])
                alert("successfully added to favorites")
           }
       }); 
  });

views.py:

 from django.http import JsonResponse

 def favorite_ajax(request):
   data = {'success': False} 
   if request.method=='POST':
      book = request.POST.get('userbooks')
      fav = FavBooks()
      fav.book_id = book
      fav.user_id = request.user
      fav.save()
      data['success'] = True
   return JsonResponse(data)
Ahtisham
  • 9,170
  • 4
  • 43
  • 57
  • i ve made the changes you suggested it was raising page isn't working error HTTP 405 – Sreesa Ranga Ramanujam Feb 01 '19 at 09:55
  • 1
    change this `url: "{% url 'home:favoriteAjax' %}",` to this `url: "/home/favoriteAjax/",` – Ahtisham Feb 01 '19 at 10:04
  • check your browser console does it show any error ? – Ahtisham Feb 01 '19 at 10:18
  • After having a look at console i found that there is an extra curly brace i ve removed it ,now it was not showing any error but it was not displaying an success message and data has not entered the data base instead in console it was showing error like POST http://localhost:8000/home/favoriteAjax/ 500 (Internal Server Error) – Sreesa Ranga Ramanujam Feb 01 '19 at 10:26
  • check your terminal from where you are running the site. It would have extra information what is causing the problem. – Ahtisham Feb 01 '19 at 10:28
  • it was showing this: ValueError at /home/favoriteAjax/ Cannot assign "'alc'": "FavBooks.book_id" must be a "UserBooks" instance.alc is the instance i want to add to the database – Sreesa Ranga Ramanujam Feb 01 '19 at 10:30
  • change this: `fav.book_id = book` to this: `fav.book_id = book.id` – Ahtisham Feb 01 '19 at 10:33
  • what that means is that when you send `userbooks` object from your template to your view via jQuery. It converts it to a string and sends it to django. What you can do is that you can either convert this string back to `userbooks` object by desalinising, Or you can access the `id` field of this string and filter your `userbooks` object by passing it the `id`. – Ahtisham Feb 01 '19 at 10:41
  • yeah !! its working now i have passed the book id instead of object,thank you very much ;):) – Sreesa Ranga Ramanujam Feb 01 '19 at 10:45