Проблемы с динамическими кнопками "нравится" и "не нравится" через шаблоны django и JS
Я пытаюсь динамически создать и использовать кнопки like и unlike для моего проекта cs50w, который, конечно, должен позволить пользователю понравиться или не понравиться сообщение и переключить кнопку like на кнопку unlike и так далее. Самое неприятное, что сама механика "нравится" и "не нравится" работает, но кнопки не работают.
- Either I can't get the opposite button to be created after I deleted
the original one via Javascript (I tried to use
appendChild
andCreateElement
, to no avail). - Or if a post has more than 1 like then more buttons show up with 2/3 of them being duds, etc.
В представлении Django я проверяю, понравилось ли текущему пользователю какое-либо сообщение (лайки находятся в собственной модели с 2 внешними ключами), затем, если сообщения есть, я отправляю их как контекст в необходимые шаблоны.
Внутри самих шаблонов я проверяю, соответствует ли пост контексту, если да, то генерирую кнопку Unlike, если нет - кнопку Like. Я уже и возился, и гуглил, но ситуация не улучшается...
Код: index.html:
network.js/liking function
function liking()
{
const divs = document.querySelectorAll(".card-footer");
divs.forEach((div) => {
const like_btn = div.querySelector('#like');
const unlike_btn = div.querySelector("#unlike");
const page_id = div.querySelector("#page_id");
if (like_btn !== null)
{
like_btn.onclick = () => {
const like_str = div.querySelector("#likes").textContent;
let like_amount = parseInt(like_str.substring(0));
like_amount++;
div.querySelector("#likes").textContent = `${like_amount.toString()} people have liked this`;
like_btn.remove();
like(page_id.textContent, "like");
};
}
if (unlike_btn !== null)
{
unlike_btn.onclick = () => {
const like_str = div.querySelector("#likes").textContent;
let like_amount = parseInt(like_str.substring(0));
if (like_amount > 0)
{
like_amount--;
div.querySelector("#likes").textContent = `${like_amount.toString()} people have liked this`;
}
else if (like_amount === 0)
{
like_amount = 0;
div.querySelector("#likes").textContent = `0 people have liked this`;
}
unlike_btn.remove();
like(page_id.textContent, "unlike");
};
}
});
}
подобная модель
class Like(models.Model):
user = models.ForeignKey(User, on_delete=CASCADE)
liked_post = models.ForeignKey(Post, on_delete=CASCADE)
def __str__(self):
return f"{self.id} - Post {self.liked_post} liked by {self.user}"
def is_valid_like(self):
return self.user != None and self.liked_post != None
представления django, которые я использую:
def index(request):
posts = Post.objects.all().order_by('-id')
pages = Paginator(posts, 10)
page_num = request.GET.get('page')
page_obj = pages.get_page(page_num)
try:
user_info = User.objects.get(username=request.user.username)
except User.DoesNotExist:
user_info=None
liked_posts = None
liked_posts = Like.objects.filter(user=user_info)
print(liked_posts)
return render(request, "network/index.html", {
"pages": page_obj,
"liked": liked_posts
})
def render_profile(request, username):
if request.method == "GET":
user_info = None
try:
user_info = User.objects.get(username=username)
except Error:
return render(request, "network/notfound.html")
posts = Post.objects.filter(user=user_info).reverse()
followers = Follow.objects.filter(followee=user_info).count()
follows = Follow.objects.filter(user=user_info).count()
is_following = True
try:
Follow.objects.get(user=request.user, followee=user_info)
except Follow.DoesNotExist:
is_following = False
liked_posts = Like.objects.filter(user=user_info)
print(liked_posts)
JsonResponse({"found": "profile has been found"}, status=200)
pages = Paginator(posts, 10)
page_num = request.GET.get('page')
page_obj = pages.get_page(page_num)
return render(request, "network/profile.html", {
"username": user_info.username,
"pages": page_obj,
"followers": followers,
"follows": follows,
"following": is_following,
"liked": liked_posts
})
Я получил этот ответ на другом форуме.
В index.html
Код:
{% if user.is_authenticated %}
{% for like in liked %}
{% if like.liked_post == page %}
<span class="is-liked-unlike"><button class="btn btn-secondary" id="unlike">Unlike</button></span>
<span class="is-liked-like"><button class="btn btn-secondary" style="display:none"
id="like">Like</button></span>
{% endif %}
{% endfor %}
<span class="is-not-liked-likeBtn"><button class="btn btn-secondary" id="like">Like</button></span>
<span class="is-not-liked-unlikedBtn"><button class="btn btn-secondary" id="unlike"
style="display:none">Unlike</button></span>
{% endif %}
В network.js, в divs.forEach:
Код:
div.querySelectorAll(".is-liked-unlike").forEach((unliked) => {
unliked.nextElementSibling.nextElementSibling.remove();
unliked.nextElementSibling.nextElementSibling.remove();
});