点赞按钮没有变成点踩,Django
当用户点击“喜欢”按钮时,应该显示相反的“讨厌”按钮,但现在并没有这样做。如果你去掉那个条件判断,那么“喜欢”和“讨厌”就可以独立工作,数据会正确地写入数据库和删除。但是,条件判断这里有问题。当用户已经点击了“喜欢”后,系统没有从数据库中获取到他们需要点击“讨厌”而不是“喜欢”的信息。我不明白为什么会这样。
models.py:
class PostLike(models.Model):
userlikepost = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
likepost = models.ForeignKey(Userpublication, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
unique_together = ('userlikepost', 'likepost')
views.py:
def show_post(request, post_slug):
post = get_object_or_404(Userpublication, slug=post_slug)
like_count = PostLike.objects.filter(likepost=post).count()
liked_by_current_user = False
if request.user.is_authenticated:
liked_by_current_user = PostLike.objects.filter(likepost=post, userlikepost=request.user).exists()
print(f'liked_by_current_user: {liked_by_current_user}')
context = {
'post': post,
'like_count': like_count,
'liked_by_current_user': liked_by_current_user,
}
return render(request, 'pie/home.html', context)
@login_required
def like_post(request, post_id):
try:
post = Userpublication.objects.get(pk=post_id)
like, created = PostLike.objects.get_or_create(userlikepost=request.user, likepost=post)
like_count = PostLike.objects.filter(likepost=post).count()
like_count = PostLike.objects.filter(likepost=post).aggregate(count=Count('id'))['count']
return JsonResponse({'liked': created, 'like_count': like_count})
except Exception as e:
return JsonResponse({'error': str(e)}, status=500)
@login_required
def unlike_post(request, post_id):
try:
post = Userpublication.objects.get(pk=post_id)
like = PostLike.objects.filter(userlikepost=request.user, likepost=post).first()
if like:
like.delete()
like_count = PostLike.objects.filter(likepost=post).count()
return JsonResponse({'unliked': True, 'like_count': like_count})
except Exception as e:
return JsonResponse({'error': str(e)}, status=500)
html:
{% if post.liked_by_current_user %}
<div class="unlike-button" data-post-id="{{ post.id }}">Dislike<span class="like-count-value" data-post-id="{{ post.id }}">{{ like_count }}</span></div>
{% else %}
<div class="like-button" data-post-id="{{ post.id }}">Like<span class="like-count-value" data-post-id="{{ post.id }}">{{ like_count }}</span></div>
{% endif %}
JS:
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function() {
function updateLikeCount(postId, likeCount) {
$('#like-count-' + postId + ' .like-count-value').text(likeCount);
}
$('.like-button').click(function() {
var postId = $(this).data('post-id');
var csrfToken = '{{ csrf_token }}';
$.ajax({
type: 'POST',
headers: {
'X-CSRFToken': csrfToken
},
url: '/like/' + postId + '/',
success: function(data) {
if (data.liked) {
updateLikeCount(postId, data.like_count);
}
},
error: function(xhr, status, error) {
console.error(xhr.responseText);
}
});
});
$('.unlike-button').click(function() {
var postId = $(this).data('post-id');
var csrfToken = '{{ csrf_token }}';
$.ajax({
type: 'POST',
headers: {
'X-CSRFToken': csrfToken
},
url: '/unlike/' + postId + '/',
success: function(data) {
if (data.unliked) {
updateLikeCount(postId, data.like_count);
}
},
error: function(xhr, status, error) {
console.error(xhr.responseText);
}
});
});
});
</script>
<script>
$(document).ready(function() {
function updateLikeCount() {
$('.like-count-value').each(function() {
var postId = $(this).data('post-id');
var likeCountElement = $(this);
$.ajax({
type: 'GET',
url: '/get_like_count/' + postId + '/',
success: function(data) {
var likeCount = parseInt(data.like_count);
if (!isNaN(likeCount)) {
likeCountElement.text(likeCount);
}
},
error: function(xhr, status, error) {
console.error(xhr.responseText);
}
});
});
}
updateLikeCount();
$('.like-button').click(function() {
var postId = $(this).data('post-id');
var csrfToken = '{{ csrf_token }}';
$.ajax({
type: 'POST',
headers: {
'X-CSRFToken': csrfToken
},
url: '/like/' + postId + '/',
success: function(data) {
if (data.liked) {
updateLikeCount();
}
},
error: function(xhr, status, error) {
console.error(xhr.responseText);
}
});
});
$('.unlike-button').click(function() {
var postId = $(this).data('post-id');
var csrfToken = '{{ csrf_token }}';
$.ajax({
type: 'POST',
headers: {
'X-CSRFToken': csrfToken
},
url: '/unlike/' + postId + '/',
success: function(data) {
if (data.unliked) {
updateLikeCount();
}
},
error: function(xhr, status, error) {
console.error(xhr.responseText);
}
});
});
});
</script>
1 个回答
0
几点说明
- 你的上下文变量应该这样称呼:
{% if liked_by_current_user %}
因为它是一个独立的上下文变量,不是post的方法或属性。
- 你的If语句是在模板里面的。它不会改变,除非页面被重新加载,模板才会重新计算。不过,因为你使用了ajax来提交点赞或点踩,所以页面不会重新加载,因此模板不会提供新的HTML。
解决这个问题最简单的方法是,在你的ajax成功方法中添加代码来改变按钮的状态。所以如果要把“点赞”改成“点踩”,可以这样做:
//find the button
buttonToChange = document.querySelector("[data-post-id='" + postID + "']")
//toggle the button class
buttonToChange.classList.add('unlike-button')
buttonToChange.classList.toggle('like-button')
//change the button text
buttonToChange.textContent = ButtonToChange.textContent.replace("Like", "Dislike")