XMLHttpRequest Synchronous Error in Bootstrap modal and Django - javascript

The program open Bootstrap Modal and load Django Form to create new permission, this is works. But when i want in the form add new Ajax call to load dynamically elements in Django ChoiceField appears the error and browser not finish the call never.
I open browser inspect console and appears XMLHttpRequest error
url.py:
path('permisos/', general_views.permission_list,name='permission_list'),
path('permisos/crear', general_views.permission_create, name='permission_create'),
path('permisos/<int:id>/editar', general_views.permission_update, name='permission_update'),
path('permisos/<int:id>/detalle', general_views.permission_detail, name='permission_detail'),
path('permisos/<int:id>/borrar', general_views.permission_delete, name='permission_delete'),
path('permisos/crear/cargar_elementos/', general_views.permission_load, name='ajax_load_permissions'),
never get to call this function from ajax
views.py:
def permission_load(request):
type = request.GET.get('type')
if type == 2: # object
list = ['general', 'billing', 'accounting']
elements = ContentType.objects.filter(app_label__in=list)
elif type == 3: # instance
list = ['general', 'billing', 'accounting']
content_type = ContentType.objects.filter(app_label__in=list)
elements = general_models.content_type.model.objects.all()
elif type == 4: # attribute
list = ['general', 'billing', 'accounting']
content_type = ContentType.objects.filter(app_label__in=list)
elements = general_models.content_type.model.objects.all()
# get instance atributtes
else: # module
elements = general_models.Modules.objects.all()
# other aspect is that i dont know how to load view result in the html choicefield
response = { 'element': elements }
json = simplejson.dumps(response)
return HttpResponse(json, mimetype="text/json")
forms.py:
class CustomPermisisonForm(forms.Form):
name = forms.CharField()
ACTION_TYPE = ((1, ('Ver')),(2, ('Añadir')),(3, ('Modificar')),(4, ('Borrar')))
action = forms.MultipleChoiceField(choices=ACTION_TYPE, label='Acciones', initial=1, widget=forms.SelectMultiple())
PERMISSION_TYPE = ((1, ('Módulo')),(2, ('Objecto')),(3, ('Instancia')),(4, ('Atributo')))
type = forms.ChoiceField(choices=PERMISSION_TYPE, label='Tipo', initial=1, widget=forms.Select(attrs={"data-objects-url":"{% url 'ajax_load_permissions' %}"}))
element = forms.ModelChoiceField(queryset=general_models.Module.objects.all())
permissions.html:
{% block javascript %}
<script src="{% static 'js/permissions.js' %}"></script>
{% endblock %}
# this is the line to open modal
<button type="button" onclick="return openModalPermission('{% url 'general:permission_create' %}')" class="btn btn-outline-primary float-right btn-sm">
<span class="fas fa-plus"></span>
</button>
permission_create.html:
{% load static %}
<div class="modal-dialog modal-lg">
<div class="modal-content">
<form method="POST" action="{% url 'general:permission_create' %}">
{% csrf_token %}
<div class="modal-header">
<h4 class="modal-title">Nuevo Permiso</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
{% include 'permission_form.html' %}
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">Crear</button>
</div>
</form>
</div>
</div>
# when comment this line the error disappear but don't work js call
<script src="{% static 'js/permissions.js' %}"></script>
permission_form.html:
{% load widget_tweaks %}
{% load static %}
{% for field in form %}
<div class="form-group{% if field.errors %} has-error{% endif %}">
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
{% render_field field class="form-control" %}
{% for error in field.errors %}
<p class="help-block">{{ error }}</p>
{% endfor %}
</div>
{% endfor %}
permissions.js:
function openModalPermission(url) {
$('#modal-permission').load(url, function() {
$(this).modal('show');
});
return false;
}
$("#id_type").change(function () {
console.log("js function");
var url = $("id_type").attr("data-objects-url");
var type = $(this).val();
console.log(type);
console.log(url);
$.ajax({
url: url,
data: {
'type': type
},
success: function (data) {
$("#id_element").html(data);
},
error: function (qXHR, textStatus, errorThrown) {
console.log(qXHR)
console.log(textStatus)
console.log(errorThrown)
}
});
return false;
});
Anybody know how to solve this problem ?
Thanks in advance.

SOLVED
permissions.html:
<!-- pass this block to the end of the file -->
{% block javascript %}
<script src="{% static 'js/permissions.js' %}"></script>
{% endblock %}

Related

sorting messages with tag in django template

I'm receiving a list of messages, each message has a tag. It may be "info", "warning", "danger" and "spreadsheet". I need to display the first three first and then spreadsheet's but in collapsible if there are more than 3 of them.
So for all messages BUT spreadsheet the template is:
<div class="row banner">
<ul class="banner-message">
{% for message in messages %}
<li{% if message.tags %} class="banner-message--{{ message.tags }}" {% else %} class="banner-message--info" {% endif %}>
<div class="message-content">
<p>{{ message|safe }}</p>
<span class="close">×</span></div>
</li>
{% endfor %}
</ul>
</div>
For tags with "spreadsheet" tag the template is:
<div class="row banner">
<ul class="banner-message">
{% for message in messages %}
<li class="{% if forloop.counter >= 3 %}collapsible_content{% endif %} banner-message--info">
<div class='message-content'>
<p>{{ message|safe }}</p>
<span class="close">×</span>
</div>
</li>
{% endfor %}
{% if messages|length > 3 %}
<button id="show_more" class="btn btn-secondary collapsible_button">Show all</button>
{% endif %}
</ul>
</div>
Where button is shown for spreadsheet messages if there are more then 3 of them and shows all of them on click.
Problem is that I receive these messages in one array and I have no guarantee that they won't be all mixed up in different order.
I need to sort them somehow with message.tags to two separate arrays? Or use some smart if but I cannot figure out how to achieve that in the template. Could you please help?
EDIT:
After comment below I am trying to sort the messages in the view.py
m = messages.get_messages(request)
if len(m) > 0:
context['msgs'] = m.filter(tags__in=['info', 'warning', 'danger']).order_by('tags')
context['spreadsheet'] = m.filter(tags='spreadsheet')
m is FallbackStorage object and it doesn't have filter method. m.objects and FallbackStorage.objects do not work either (for the same reason: has no attribute 'objects'). I've tried to do all above with messages straight away (without the get_messages method) but the result is the same. How to filter this correctly?
get_messages is a utility function and not a class method. You can read more about how to use it in the docs here.
In your view you can do:
from django.contrib.messages import get_messages
...
message_list = get_messages(request)
messages = []
spreadsheet_messages = []
for message in message_list:
tags = message.tags
if ("info" in tags) or ("warning" in tags) or ("danger" in tags):
messages.append(message)
if "spreadsheet" in tags:
spreadsheet_messages.append(message)
context["messages"] = messages
context["spreadsheet"] = spreadsheet_messages
...
you can divide messages in two different querysets. On your views.py:
context['messages'] = messages.filter(tags__in = ['info','warning','danger']).order_by('tags')
context['spreadsheet'] = messages.filter(tags = 'spreadsheet')
On your template:
<div class="row banner">
<ul class="banner-message">
{% for message in messages %}
<li{% if message.tags %} class="banner-message--{{ message.tags }}" {% else %} class="banner-message--info" {% endif %}>
<div class="message-content">
<p>{{ message|safe }}</p>
<span class="close">×</span></div>
</li>
{% endfor %}
</ul>
</div>
<div class="row banner">
<ul class="banner-message">
{% for message in spreadsheet %}
<li class="{% if forloop.counter >= 3 %}collapsible_content{% endif %} banner-message--info">
<div class='message-content'>
<p>{{ message|safe }}</p>
<span class="close">×</span>
</div>
</li>
{% endfor %}
{% if messages|length > 3 %}
<button id="show_more" class="btn btn-secondary collapsible_button">Show all</button>
{% endif %}
</ul>
</div>
EDIT:
According to you comment. I suggest to try something like this:
msgs = []
spreadsheet = []
m = messages.get_messages(request)
if len(m) > 0:
for mensaje in m:
#TRY THE THREE OPTIONS BECAUSE I DON'T KNOW THE MESSAGES' STRUCTURE#
if 'spreadsheet' in message['tags']:
#if 'spreadsheet' in message.tags:
#if 'spreadshhet' in message.tags():
spreadsheet.append(mensaje)
else:
msgs.append(mensaje)
context['msgs'] = msgs
context['spreadsheet'] = spreadsheet

infinite scroll working but not populating all data because of javascript call

In my web site I want to show the user ratings - for that I used the infinite scroll but I am facing one problem.
When it first loads the data before calling the <a class="infinite-more-link" href="?page={{ ratings.next_page_number }}"></a> it is showing the star with the count of vote,but when after calling the <a class="infinite-more-link" href="?page={{ ratings.next_page_number }}"></a> it is not showing the star.
my views.py
#login_required
def ratings_user(request,pk):
ratings = VoteUser.objects.filter(the_user_id=pk).order_by('-pk')
paginator = Paginator(ratings, 1)
page = request.GET.get('page')
try:
posts = paginator.page(page)
except PageNotAnInteger:
posts = paginator.page(1)
except EmptyPage:
posts = paginator.page(paginator.num_pages)
return render(request,request.session['is_mobile']+'profile/ratings.html',{'ratings':posts})
html
{% extends 'mobile/profile/base.html' %}
{% block title %}
Ratings
{% endblock %}
{% block leftcontent %}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/all.min.css" rel="stylesheet">
{% endblock %}
{% block middlecontent %}
<div class="infinite-container">
{% for i in ratings %}
<div class="infinite-item">
<div class="w3-container w3-card w3-white w3-round w3-margin">
<img src="{{ i.the_user.profile.avatar.url }}" alt="Avatar" class="w3-left w3-circle w3-margin-right" style="width:40px;height:40px;border-radius:50%;">
{% with user=i.the_user.profile %}{{ user.prenom|title|truncatewords:2 }} {{ user.nom|title|truncatewords:1 }}{% endwith %}
<br>
<span class="stars" data-rating="{{ i.vote.vote }}" data-num-stars="5" ></span>
<hr class="w3-clear">
<p>
{{ i.commentaire|linebreaksbr }}
</p>
<span class="glyphicon glyphicon-user"></span> {% with user=i.the_sender.profile %}{{ user.prenom|title|truncatewords:2 }} {{ user.nom|title|truncatewords:1 }}{% endwith %}
</div>
</div>
{% endfor %}
</div>
{% if ratings.has_next %}
<a class="infinite-more-link" href="?page={{ ratings.next_page_number }}"></a>
{% endif %}
{% endblock %}
{% block rightcontent %}
{% endblock %}
{% block js %}
<script>
var infinite = new Waypoint.Infinite({
element: $('.infinite-container')[0]
});
</script>
<script>
//ES5
$.fn.stars = function() {
return $(this).each(function() {
var rating = $(this).data("rating");
var fullStar = new Array(Math.floor(rating + 1)).join('<i class="fas fa-star"></i>');
var halfStar = ((rating%1) !== 0) ? '<i class="fas fa-star-half-alt"></i>': '';
var noStar = new Array(Math.floor($(this).data("numStars") + 1 - rating)).join('<i class="far fa-star"></i>');
$(this).html(fullStar + halfStar + noStar);
});
}
//ES6
$.fn.stars = function() {
return $(this).each(function() {
const rating = $(this).data("rating");
const numStars = $(this).data("numStars");
const fullStar = '<i class="fas fa-star"></i>'.repeat(Math.floor(rating));
const halfStar = (rating%1!== 0) ? '<i class="fas fa-star-half-alt"></i>': '';
const noStar = '<i class="far fa-star"></i>'.repeat(Math.floor(numStars-rating));
$(this).html(`${fullStar}${halfStar}${noStar}`);
});
}
</script>
<script>
$(function(){
$('.stars').stars();
});
</script>
{% endblock %}
I have tried to put the <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/all.min.css" rel="stylesheet"> inside the class="infinite-item" but it does not help.what might be the reason for that ? Thanks.
Since yesterday I am on this question I tried everything.
This is another user that has tried to help me here https://stackoverflow.com/a/69930878/15042684 but I did not really understand could you please help me to understand it with some code.
this is his answer:
It doesn't look like .stars() will look for new elements being added to the DOM. You should look for a callback function configuration option within Waypoint.Infinite that you can call .stars() on the new elements.
Assuming you are using waypoint's Infinite Scroll, you can use the onAfterPageLoad callback
onAfterPageLoad
Default: $.noop.
Parameters: $items.
This is a callback that will fire at the end of the request cycle, after new items have been appended to the container. It is passed one parameter, which is a jQuery object of all the items that were appended during the page load.
Note that despite using the jquery convention of $name indicates a jquery object and stating is a jquery object, in this case, trial and error shows that $items are the DOM elements, not a jquery object.
No example provided in the docs, so it will probably look something like:
<script>
var infinite = new Waypoint.Infinite({
element: $('.infinite-container')[0],
onAfterPageLoad: function(items) {
$(items).find(".stars").stars();
}
});
</script>

JavaScript: unable to disable/enable an input button

I'm building a web app using the Django framework. I'm attempting to use some JavaScript to disable a button that users can press to submit a text-based review.
The JavaScript in the listing.js file looks as follows:
document.addEventListener('DOMContentLoaded', function () {
hide_submit_review_button();
});
// Hide the 'Submit Review'button until the user begins typing a review
// Prevent the user from typing more than 100 characters
function hide_submit_review_button() {
var submit_review_button = document.getElementById('submit-review-button');
if (submit_review_button !== null) {
document.getElementById('submit-review-button').disabled = true;
document.getElementById('review-contents').onkeyup = () => {
if ((document.getElementById('review-contents').value.length > 0 &&
document.getElementById('review-contents').value.length <= 100 )) {
document.getElementById('submit-review-button').disabled = false;
} else {
document.getElementById('submit-review-button').disabled = true;
}
};
}
}
In my listing.html file, I identify the review-contents and submit-review-button. Here's the code:
{% extends "layout.html" %}
{% load static %}
{% block body %}
{% if user.is_authenticated %}
<form action="{% url 'review' listing.id %}" method="POST">
{% csrf_token %}
<input type="text" class="form-control" name="review" id="review-contents" placeholder="Write a review...">
<input class="btn btn-primary mt-1" type="submit" id="submit-review-button" value="Submit Review">
</form>
{% endif %}
{% endblock %}
{% block script %}
{% if user.is_authenticated %}
{{ block.super }}
<script src="{% static 'listing.js' %}"></script>
{% endif %}
{% endblock %}
An example of a page where the button appears is: http://127.0.0.1:8000/listings/7
And, here is what the urls.py file looks like (if it matters):
urlpatterns = [
path('', views.index, name='index'),
path('listings/<int:listing_id>', views.listing, name='listing'),
]
Can anyone see why this button doesn't disable?
Thanks!
The problem resulted from not having the following in the header tag in the layout.html file:
{% block script %}
{% endblock %}

Django AJAX Infinite Scroll Error on page reload

I'm trying to implement infinite scroll with django and jquery(Waypoint).
I have a ListView with a pagination of 5, but when waypoint loads second page, AJAX requests are no longer performed so I added the AJAX function on the onAfterPageLoad which helps bring back AJAX function to the newly loaded page.
That's fine, but then it introduces a bug to my code making the page loaded initially (First Page) no longer perform AJAX functions very well. It makes AJAX on the first page run 3 times if I just loaded a third page and makes AJAX on the second page run twice and so on depending on the number of pages loaded already.
I don't know if there are any cool ways to achieve this because I tried using just jquery without waypoint, but still get same errors as I get when using just waypoint making it an error. This is kinda tricky so far.
{% extends "base.html" %}
{% block content %}
{% load static %}
<div class="container" style="max-width:700px">
<div class="px-3 pt-md-5 pb-md-4 mx-auto text-center">
<h1 class="display-4">All Groups</h1>
<p class="lead">List of groups</p>
</div>
<div class="">
<div class="row infinite-container">
{% for group in groups %}
<div class="col-md-12 infinite-item">
<!-- <img class="img-fluid" src="https://picsum.photos/700"> -->
<a class="text-dark" href="{{ group.get_absolute_url }}">
<div class="card mb-4 box-shadow">
<div class="card-body">
<h2 style="font-size:18px;font-weight:bold;min-height:42px;">
{{group.name|truncatechars:50}}</h2>
<div class="d-flex justify-content-between align-items-center">
<small class="text-muted">{{group.owner}}</small>
<small class="text-muted">{{group.date_created}}</small>
</div>
<p><a class='follow-btn' data-href='{{ group.get_group_follow_api_url }}'
data-likes='{{ page.likes.count }}'
href='{{ group.get_group_follow_url }}'>{{ group.follows.count }}
{% if request.user.profile in group.follows.all %}
Unfollow
{% else %}
Follow
{% endif %}
</a></p>
</div>
</div>
</a>
</div>
{% endfor %}
</div>
<!-- Comment for loading spinner -->
{% comment %}
<div class="d-flex d-none position-fixed" style="top:35vh;left:46vw">
<button class="btn btn-primary loading">
<span class="spinner-border spinner-border-sm"></span>
Loading...
</button>
</div>
{% endcomment %}
<!-- End of comment for loading spinner -->
<div class="row">
<div class="col-12">
{% if page_obj.has_next %}
<a class="infinite-more-link" href="?page={{ page_obj.next_page_number }}"></a>
{% endif %}
</span>
</div>
</div>
</div>
</div>
<script src="{% static "js/jquery.waypoints.min.js" %}"></script>
<script src="/static/js/infinite.min.js"></script>
<script>
var infinite = new Waypoint.Infinite({
element: $('.infinite-container')[0],
offset: 'bottom-in-view',
onBeforePageLoad: function () {
$('.loading').show();
},
onAfterPageLoad: function () {
$('.loading').hide();
$(document).ready(function(){
function updateText(btn, newCount, verb){
btn.text(newCount + " " + verb)
}
$(".follow-btn").click(function(e){
e.preventDefault()
var this_ = $(this)
var badge = this_.find('.unlike-update')
var followUrl = this_.attr("data-href")
var followCount = parseInt(this_.attr("data-follows")) | 0
var addFollow = followCount + 1
var removeFollow = followCount - 1
if (followUrl){
$.ajax({
url: followUrl,
method: "GET",
data: {},
success: function(data){
console.log(data)
var newFollows;
if (data.followed){
// updateText(this_, addLike, "Unlike")
// updateText(this_, data.likescount, badge)
updateText(this_, data.followscount, "Unfollow")
} else {
// updateText(this_, removeLike, "Like")
updateText(this_, data.followscount, "Follow")
// remove one like
}
}, error: function(error){
console.log(error)
console.log("error")
}
})
}
})
})
}})
</script>
{% include 'group/snippets/group_follow.html' %}
{% endblock %}
class GroupListView(LoginRequiredMixin, ListView):
model = Group
paginate_by = 5
context_object_name = 'groups'
template_name = 'group/group_list.html'
ordering = ['-date_created']

Adding items to Wishlist | Django

I've got this system where I want to add in a favoriting feature where when someone clicks on the like button on a card it gets saved and displayed at port/wishlist.html but not able to go about and solve it, here is my Github Repository and some main codes.
models.py
from django.db import models
from django.contrib.auth.models import User
import datetime
YEAR_CHOICES = []
for r in range(1980, (datetime.datetime.now().year + 1)):
YEAR_CHOICES.append((r, r))
class Music(models.Model):
song = models.CharField(max_length=50, blank=False)
pic = models.ImageField(blank=False, null=True)
published_year = models.IntegerField(('year'), choices=YEAR_CHOICES, default=datetime.datetime.now().year)
description = models.CharField(max_length=80)
def __str__(self):
return self.song
class Wishlist(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE,null=True)
music = models.ForeignKey(Music, on_delete=models.DO_NOTHING)
views.py
#login_required
def liked(request):
if request.method == "POST":
if user.is_authenticated:
# takes in the specific card id that is been liked and saves it and displays on Port/wishlist.html
music.save()
else:
return HttpResponse("Your card is Invalid")
else:
return HttpResponse("Your request is Invalid")
return render(request, template_name='main/wishlist.html', context={"wishlist": Wishlist.objects.all})
like.js
$(document).ready(function(){
$(".like").click(function(){
$(this).toggleClass("heart");
});
});
I would suggest doing something like this:
Here we create a new url for add to wishlist(add_to_wishlist). In like.js pass music_id through ajax with POST.If a user is login then show user's wishlisted product as heart symbol as red. And you can show wishlisted product through link in template. You can Understand all others in my code. Please try this. Thanks.
urls.py
from django.urls import path
from main import views
app_name = 'main'
urlpatterns = [
path('', views.home, name='home'),
path('signup/', views.signup, name='signup'),
path('wishlist/', views.liked, name='liked'),
path('login/', views.login_req, name='login'),
path('logout/', views.logout_req, name='logout'),
path('add-to-wishlist/', views.add_to_wishlist, name='add_to_wishlist'), # For add to wishlist
]
views.py
def home(request):
wishlisted_list =[]
if request.user.is_authenticated:
wishlisted_list = list(Wishlist.objects.filter(user_id=request.user).values_list('music_id',flat=True).order_by('music_id'))
return render(request, template_name='main/home.html', context={"music": Music.objects.all(),'wishlisted_list':wishlisted_list})
#login_required
def liked(request):
wishlist = {}
if request.method == "GET":
if request.user.is_authenticated:
wishlist = Wishlist.objects.filter(user_id_id=request.user.pk)
else:
print("Please login")
return HttpResponse("login")
return render(request, template_name='main/wishlist.html', context={"wishlist": wishlist})
#login_required
def add_to_wishlist(request):
if request.is_ajax() and request.POST and 'attr_id' in request.POST:
if request.user.is_authenticated:
data = Wishlist.objects.filter(user_id_id = request.user.pk,music_id_id = int(request.POST['attr_id']))
if data.exists():
data.delete()
else:
Wishlist.objects.create(user_id_id = request.user.pk,music_id_id = int(request.POST['attr_id']))
else:
print("No Product is Found")
return redirect("main:home")
like.js
$(document).ready(function(){
$(".like").click(function(){
var attr_id = $(this).attr('attr_id')
var action_url = $(this).attr('action_url')
var that = $(this)
$.ajax({
url: action_url,
type: "POST",
data: {'attr_id': attr_id },
headers: { "X-CSRFToken": $.cookie("csrftoken") },
success: function (result) {
console.log("Success")
that.toggleClass("heart");
},
error: function () {
alert("Please login");
}
});
});
});
home.html
{% load static %}
<link rel="stylesheet" href="{% static 'main/home.css' %}" type="text/css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.13.0/css/all.css" integrity="sha384-Bfad6CLCknfcloXFOyFnlgtENryhrpZCe29RTifKEixXQZ38WheV+i/6YWSzkz3V" crossorigin="anonymous">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
Hey there,
{% if user.is_authenticated %}
<h1>{{user.username}}</h1>
{% else %}
<h1>unknown</h1>
{% endif %}
<a href="{% url 'main:liked' %}" >Wishlist</a>
<section class="cards">
{% for m in music %}
<div class="card">
<div class="top">
<div class="label1">{{m.song}}</div>
{% if m.pk in wishlisted_list %}
{% for i in wishlisted_list %}
{% if m.pk is i %}
<span class="like heart" id="id" attr_id="{{m.pk}}" action_url="{% url 'main:add_to_wishlist' %}"><i class="fa fa-heart"></i></span>
{% endif %}
{% endfor %}
{% else %}
<span class="like" id="id" attr_id="{{m.pk}}" action_url="{% url 'main:add_to_wishlist' %}"><i class="fa fa-heart"></i></span>
{% endif %}
</div>
<div class="middle">
<a href="https://google.com" id="link" target="_blank">
<div class="img-container"><img src="{{ m.pic.url }}"></div>
</a>
</div>
<a href="https://google.com" id="link" target="_blank">
<div class="bottom">
<div class="label4">{{m.description}}</div>
</div>
</a>
</div>
{% endfor %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="{% static 'main/js/like.js' %}" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js"></script>
</section>
wishlist.html
{% load static %}
<link rel="stylesheet" href="{% static 'main/home.css' %}" type="text/css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.13.0/css/all.css" integrity="sha384-Bfad6CLCknfcloXFOyFnlgtENryhrpZCe29RTifKEixXQZ38WheV+i/6YWSzkz3V" crossorigin="anonymous">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
Hey there,
{% if user.is_authenticated %}
<h1>{{user.username}}</h1>
{% else %}
<h1>unknown</h1>
{% endif %}
<a href="{% url 'main:home' %}" >Go to Home</a>
<section class="cards">
{% if wishlist %}
{% for m in wishlist %}
<div class="card">
<div class="top">
<div class="label1">{{m.music_id}}</div>
<span class="like" id="id" attr_id="{{m.music_id.pk}}" action_url="{% url 'main:add_to_wishlist' %}"></span>
</div>
<div class="middle">
<a href="https://google.com" id="link" target="_blank">
<div class="img-container"><img src="{{ m.music_id.pic.url }}"></div>
</a>
</div>
<a href="https://google.com" id="link" target="_blank">
<div class="bottom">
<div class="label4">{{m.music_id.description}}</div>
</div>
</a>
</div>
{% endfor %}
{% else %}
<div class="card">
<div class="middle">
<div class="label1">Your Wishlist is empty...!</div>
</div>
<div class="bottom">
<div class="label4">Go to Shop</div>
</div>
</div>
{% endif %}
</section>
First things first, you need to add a primary key in the Music table assuming you name it as id
In the like.js file, you'll need to make an Ajax call to send the music ID to Django. Pass the music ID to the template when you render it so that you can pass it back during the Ajax call
like.js
$.ajax(path, {
data: {"music_id": 12345},
method: "POST",
success: function (data, textStatus, jqXHR) {
$(selector).toggleClass("heart");
},
error: function () {
console.log("Something went wrong");
}
Now, in you view, you can have something like this
view.py
def add_to_wishlist(request):
data = json.loads(request.body.decode("utf-8"))
user_id = request.user.id
music_id = data.get('domain_name'))
wishlist = Wishlist()
wishlist.user_id = user_id
wishlist.music_id = music_id
wishlist.save()

Categories