Как создать кнопки "нравится/не нравится" для нескольких полей в модели Django без перезагрузки страницы?

Моя модель

from django.db import models


# Create your models here.
class Musician(models.Model):
    name_of_blog_maker = models.CharField(max_length=200, null=True, blank=True)
    name_of_musician = models.CharField(max_length=200)
    name_of_band = models.CharField(max_length=200)
    published_date = models.DateTimeField("Published At", blank=True, null=True)
    appreciation = models.TextField(null=True, blank=True)
    cover = models.ImageField(upload_to="images/", default=None)
    music_1 = models.FileField(upload_to="music/", default=None)
    music_1_name = models.CharField(max_length=200, null=True, blank=True)
    music_1_votes = models.IntegerField(default=0)
    music_1_users = models.JSONField(default=dict)
    music_2 = models.FileField(upload_to="music/", default=None)
    music_2_name = models.CharField(max_length=200, null=True, blank=True)
    music_2_votes = models.IntegerField(default=0)
    music_2_users = models.JSONField(default=dict)
    music_3 = models.FileField(upload_to="music/", default=None)
    music_3_name = models.CharField(max_length=200, null=True, blank=True)
    music_3_votes = models.IntegerField(default=0)
    music_3_users = models.JSONField(default=dict)
    
    def __str__(self):
        return self.name_of_musician

В моей модели "Музыкант" "music_1_votes" хранится количество голосов всех зарегистрированных пользователей за "music_1". В "music_1_users" хранятся "username" и "user_id" в формате словаря. То же самое относится к music_2 и music_3.

Мой взгляд

class MusicianDetailView(DetailView):
    model = Musician
    template_name = "guitar_blog/blog_detail.html"

    def post(self, request, **kwargs):
        song = self.get_object()
        user_id = request.user.id
        user_username = request.user.username

        if request.user.is_authenticated:
            if "Like1" in request.POST and user_username not in song.music_1_users.keys():
                song.music_1_votes += 1
                song.music_1_users[user_username] = user_id
                song.save()

            elif "Unlike1" in request.POST and user_username in song.music_1_users.keys():
                song.music_1_votes -= 1
                song.music_1_users.pop(user_username)
                song.save()

            elif "Like2" in request.POST and user_username not in song.music_2_users.keys():
                song.music_2_votes += 1
                song.music_2_users[user_username] = user_id
                song.save()

            elif "Unlike2" in request.POST and user_username in song.music_2_users.keys():
                song.music_2_votes -= 1
                song.music_2_users.pop(user_username)
                song.save()

            elif "Like3" in request.POST and user_username not in song.music_3_users.keys():
                song.music_3_votes += 1
                song.music_3_users[user_username] = user_id
                song.save()

            elif "Unlike3" in request.POST and user_username in song.music_3_users.keys():
                song.music_3_votes -= 1
                song.music_3_users.pop(user_username)
                song.save()

        context = {
            "musician": self.get_object(),
        }
        return render(request, self.template_name, context)

В моем "View", внутри "post function" я проверяю, есть ли имя кнопки, нажатой в "файле шаблона" в запросе поста, когда пользователь вошел в систему. Если name="Like1" и {username: user_id} нет в music_1_users из My Model, я увеличиваю "music_1_votes в файле My Model" на 1 и создаю пару ключ-значение "{username: user_id} из запроса на пост" в "music_1_users in my Model File" и затем сохраняем ее. Если name="Unlike1" и {username: user_id} в music_1_users, то я уменьшаю music_1_votes на 1 и вытаскиваю {username: user_id} из music_1_users. То же самое происходит для music_2 и music_3. Затем я создаю контекстный объект и затем рендерингую его с помощью template.

Мой шаблон

В моем шаблоне в "song1 div" у меня есть форма, в которой если music_1_users.keys() содержит имя пользователя, то будет показана кнопка Unlike1 named, иначе, Like1 named. Наряду с похожими будут также показаны class="after-like". Это относится и к песне2, песне3.

Мой вопрос

Все мои функциональные возможности работают абсолютно нормально. Все, что я хочу, это чтобы это происходило без перезагрузки страницы . Я попробовал Ajax, но не смог понять, как другие люди используют его. Они используют различную модель для голосов, и они также используют many_to_many_fields для этой цели. И большинство из них используют представления на основе функций. Я также пробовал возвращать Jsonresponse с моими music_1_votes (для 2, 3 также) в моем View. Но моя функция ajax: success function даже не может получить доступ к ответу. Если перезагрузку страницы нельзя остановить без ajax, то как это сделать? и если это можно сделать без ajax, то как это сделать? Должен ли я уничтожить весь этот код, который я набрал? Кто-нибудь может мне помочь?

Спасибо!

Вернуться на верх