I’m making a music stereaming website with Django and i’m struggling with adding a song to liked songs. I have a {% for % } that cycle all the songs and when i click the hearth button i want the song to be added to liked songs. How can i fix it?
models.py (for songs and songs being liked):
class Song(models.Model):
song_id = models.AutoField(primary_key=True)
name = models.CharField(max_length=50)
artist = models.CharField(max_length=50)
album = models.CharField(max_length=50, blank=True)
genre = models.CharField(max_length=20, blank=True, default='genre')
song = models.FileField(upload_to="songs/", validators=[FileExtensionValidator(allowed_extensions=['mp3', 'wav'])], default="name")
image = models.ImageField(upload_to="songimage/", validators=[FileExtensionValidator(allowed_extensions=['jpeg', 'jpg', 'png'])])
data = models.DateTimeField(auto_now=False, auto_now_add=True)
slug = models.SlugField()
class LikedSong(models.Model):
liked_id = models.AutoField(primary_key=True)
user = models.ForeignKey(User, on_delete=models.CASCADE)
music_id = models.ForeignKey(Song, on_delete=models.CASCADE)
views.py (to like a song):
def likesong(request):
user = request.user
if user.is_authenticated:
if request.method == "POST":
song_id = request.POST.get('song_id')
state = request.POST.get('state')
favourites = LikedSong.objects.filter(user=user)
song = Song.objects.get(song_id=song_id)
if state == 'liked':
if song in favourites.songs.all():
favourites.delete(song)
else:
if song not in favourites.songs.all():
favourites.add(song)
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
HTML:
{% for i in allsongs %}
<div class="sameMovieCard">
<div class="container_songpost">
<img src="{{i.image.url}}" id="A_{{i.song_id}}"/>
<div class="overlay_songpost"></div>
<div class="play-btn_songpost">
<a class="play-btn" data-song-url="{{i.song.url}}" id="{{i.song_id}}" onclick="playSong(this)"><i class="fa-solid fa-circle-play"></i></a>
</div>
</div>
<div class="songpost_data">
<h5 class="song-name" id="B_{{i.song_id}}"><a data-song-url="{{i.song.url}}" id="{{i.song_id}}" onclick="playSong(this)">{{i.name}}</a></h5>
<p class="singer-name" id="C_{{i.song_id}}">{{i.artist}}</p>
{% if user.is_authenticated %}
<form id="my_form" action="{% url 'music:likesong' %}" method="post" style="margin:0">{% csrf_token %}
<input type="hidden" id="helo" value="{{i.song_id}}">
<input type="hidden" id="state" name="state" value="{{ state }}">
<button type="submit" id="submitlike" style="color: red; margin-top: 15px;">
<a id="likeButton" class="fa-regular fa-heart fa-2x {% if state == 'liked' %}liked{% endif %}" data-song-id="{{i.song_id}}" style="color: black; margin-bottom:20px;" onclick="toggleHeart(this)"></a>
</button>
</form>
{% endif %}
</div>
</div>
{% endfor %}
JavaScript function (to get the state and to change hearth color):
document.getElementById('likeButton').addEventListener('click', function(e) {
e.preventDefault();
var stateElement = document.getElementById('state').value;
var currentState = stateElement.value;
var newState = currentState === 'liked' ? '' : 'liked';
stateElement.value = newState;
if (newState === 'liked') {
document.getElementById('likeButton').classList.add('liked');
} else {
document.getElementById('likeButton').classList.remove('liked');
}
document.getElementById('my_form').submit();
});
function toggleHeart(element) {
if (element.classList.contains('fa-regular')) {
element.classList.remove('fa-regular');
element.classList.add('fas', 'heart-red');
} else {
element.classList.remove('fas', 'heart-red');
element.classList.add('fa-regular');
}
}
2