我正在尝试在Django ListView中制作类似于社交媒体供稿的Twitter,并从 Django 3 By Example 一书中添加了一个类似于Ajax的按钮。 like功能可以在DetailView中完美运行,但是我无法在ListView中使其正常工作。在DetailView中单击“喜欢”按钮时,它喜欢页面上的所有帖子,并显示“ 1个喜欢”,然后显示“ 11110个喜欢”,然后从该位置呈指数上升。喜欢/不喜欢的切换是正确的,但不会使计数减少1;反之亦然。它一直在上升。请帮忙!
Models.py:
class Post(models.Model):
content = models.TextField(max_length=150, blank=True)
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
image = models.ImageField(storage=PrivateMediaStorage(), upload_to = pics_path, blank=True, null=True)
vid = models.FileField(storage=PrivateMediaStorage(), upload_to = vids_path, blank=True, null=True)
users_like = models.ManyToManyField(User, related_name='posts_liked', blank=True)
Views.py:
@require_POST
def post_like(request):
post_id = request.POST.get('id')
action = request.POST.get('action')
if post_id and action:
try:
post = Post.objects.get(id=post_id)
if action == 'like':
post.users_like.add(request.user)
else:
post.users_like.remove(request.user)
return JsonResponse({'status':'ok'})
except:
pass
return JsonResponse({'status':'ko'})
模板aka post_list.html:
{% with total_likes=post.users_like.count users_like=post.users_like.all %}
<div class="post-info">
<div>
<span class="count">
<span class="total">{{ total_likes }}</span>
like{{ total_likes|pluralize }}
</span>
<a href="#" data-id="{{ post.id }}" data-action="{% if request.user in users_like %}un{% endif %}like" class="like button">
{% if request.user not in users_like %}
Like
{% else %}
Unlike
{% endif %}
</a>
</div>
</div>
{% endwith %}
jQuery:
var csrftoken = Cookies.get('csrftoken');
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
$(document).ready(function(){
$('a.like').click(function(e){
e.preventDefault();
$.post('{% url "like" %}',
{
id: $(this).data('id'),
action: $(this).data('action')
},
function(data){
if (data['status'] == 'ok')
{
var previous_action = $('a.like').data('action');
// toggle data-action
$('a.like').data('action', previous_action == 'like' ? 'unlike' : 'like');
// toggle link text
$('a.like').text(previous_action == 'like' ? 'Unlike' : 'Like');
// update total likes
var previous_likes = parseInt($('span.count .total').text());
$('span.count .total').text(previous_action == 'like' ? previous_likes + 1 : previous_likes - 1);
}
}
);
});
});
答案 0 :(得分:0)
好像您正在选择DOM上的所有a.like
元素一样,span.count.total
选择时应该更加具体,最好使用id。例如在<a>
中:
<a href="#" id="{{ post.id }}" data-id="{{ post.id }}" data-action="{% if request.user in users_like %}un{% endif %}like" class="like button">
然后在jQuery中使用
:$(document).ready(function(){
$('a.like').click(function(e){
e.preventDefault();
var id = $(this).data('id');
var action = $(this).data('action');
$.post('{% url "like" %}',
{
id: id,
action: action
},
function(data){
if (data['status'] == 'ok')
{
var previous_action = $('#' + id').data('action');
// toggle data-action
$('#' + id).data('action', previous_action == 'like' ? 'unlike' : 'like');
// toggle link text
$('#' + id).text(previous_action == 'like' ? 'Unlike' : 'Like');
// update total likes
var previous_likes = parseInt($('span.count .total').text());
$('#' + id + '_total').text(previous_action == 'like' ? previous_likes + 1 : previous_likes - 1);
}
}
);
});
});
与span元素相同。请记住,您应该为每个元素使用 unique id,因此也许可以附加诸如id="{{ post.id }}_like"
,id="{{ post.id }}_count"
,id="{{ post.id }}_total"
之类的后缀来区分。