Dưới đây là các ý chính của giải pháp của tôi. Tôi sử dụng hình ảnh với jQuery/AJAX để xử lý các nhấp chuột. Chịu ảnh hưởng mạnh mẽ của trang web này. Có một số công cụ có thể sử dụng một số công việc (ví dụ: xử lý lỗi trong máy khách - và phần lớn nó có thể được tái cấu trúc) nhưng hy vọng mã này hữu ích cho bạn.
HTML:
<div class="vote-buttons">
{% ifequal thisUserUpVote 0 %}
<img class="vote-up" src = "images/vote-up-off.png" title="Vote this thread UP. (click again to undo)" />
{% else %}
<img class="vote-up selected" src = "images/vote-up-on.png" title="Vote this thread UP. (click again to undo)" />
{% endifequal %}
{% ifequal thisUserDownVote 0 %}
<img class="vote-down" src = "images/vote-down-off.png" title="Vote this thread DOWN if it is innapropriate or incorrect. (click again to undo)" />
{% else %}
<img class="vote-down selected" src = "images/vote-down-on.png" title="Vote this thread DOWN if it is innapropriate or incorrect. (click again to undo)" />
{% endifequal %}
</div> <!-- .votebuttons -->
Các jQuery:
$(document).ready(function() {
$('div.vote-buttons img.vote-up').click(function() {
var id = {{ thread.id }};
var vote_type = 'up';
if ($(this).hasClass('selected')) {
var vote_action = 'recall-vote'
$.post('/ajax/thread/vote', {id:id, type:vote_type, action:vote_action}, function(response) {
if (isInt(response)) {
$('img.vote-up').removeAttr('src')
.attr('src', 'images/vote-up-off.png')
.removeClass('selected');
$('div.vote-tally span.num').html(response);
}
});
} else {
var vote_action = 'vote'
$.post('/ajax/thread/vote', {id:id, type:vote_type, action:vote_action}, function(response) {
if (isInt(response)) {
$('img.vote-up').removeAttr('src')
.attr('src', 'images/vote-up-on.png')
.addClass('selected');
$('div.vote-tally span.num').html(response);
}
});
}
});
Quan điểm Django để xử lý yêu cầu AJAX:
def vote(request):
thread_id = int(request.POST.get('id'))
vote_type = request.POST.get('type')
vote_action = request.POST.get('action')
thread = get_object_or_404(Thread, pk=thread_id)
thisUserUpVote = thread.userUpVotes.filter(id = request.user.id).count()
thisUserDownVote = thread.userDownVotes.filter(id = request.user.id).count()
if (vote_action == 'vote'):
if (thisUserUpVote == 0) and (thisUserDownVote == 0):
if (vote_type == 'up'):
thread.userUpVotes.add(request.user)
elif (vote_type == 'down'):
thread.userDownVotes.add(request.user)
else:
return HttpResponse('error-unknown vote type')
else:
return HttpResponse('error - already voted', thisUserUpVote, thisUserDownVote)
elif (vote_action == 'recall-vote'):
if (vote_type == 'up') and (thisUserUpVote == 1):
thread.userUpVotes.remove(request.user)
elif (vote_type == 'down') and (thisUserDownVote ==1):
thread.userDownVotes.remove(request.user)
else:
return HttpResponse('error - unknown vote type or no vote to recall')
else:
return HttpResponse('error - bad action')
num_votes = thread.userUpVotes.count() - thread.userDownVotes.count()
return HttpResponse(num_votes)
Và những phần liên quan của mô hình Chủ đề:
class Thread(models.Model):
# ...
userUpVotes = models.ManyToManyField(User, blank=True, related_name='threadUpVotes')
userDownVotes = models.ManyToManyField(User, blank=True, related_name='threadDownVotes')
Nguồn
2009-10-07 04:55:55
Điều này có thể hữu ích. Chỉ cần nhìn vào nó ngay bây giờ. Bạn có biết những gì từ liên kết devdocs.apps.kb.models Liên kết phải được thay đổi thành? –
Lợi thế của mã này trong câu trả lời của tôi là nâng cao tiến bộ - nó sẽ hoạt động mà không có Javascript, nhưng bạn có thể thêm AJAX lên trên để làm cho trải nghiệm người dùng tốt hơn. –
thay thế devdocs.apps.kb.models bằng đường dẫn đến tệp models.py của bạn nơi bạn xác định Liên kết. Nó sẽ giống như yourprojectname.yourappname.models. –