python Django 投票上/下方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1528583/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Django Vote Up/Down method
提问by irl_irl
I am making a small app that lets users vote items either up or down. I'm using Django (and new to it!).
我正在制作一个小应用程序,让用户可以对项目进行上下投票。我正在使用 Django(而且是新手!)。
I am just wondering, what is the best way to present the upvote link to the user. As a link, button or something else?
我只是想知道,向用户展示 upvote 链接的最佳方式是什么。作为链接,按钮或其他什么?
I have already done something like this in php with a different framework but I'm not sure if I can do it the same way. Should I have a method for up/down vote and then display a link to the user to click. When they click it, it performs the method and refreshes the page?
我已经用不同的框架在 php 中做过类似的事情,但我不确定我是否可以用同样的方式来做。我应该有一种向上/向下投票的方法,然后向用户显示一个链接以供点击。当他们点击它时,它会执行该方法并刷新页面?
采纳答案by panchicore
Just plug and play:
只需即插即用:
RedditStyleVoting
Implementing reddit style voting for any Model with django-voting
http://code.google.com/p/django-voting/wiki/RedditStyleVoting
RedditStyleVoting
使用 django-voting 为任何模型实施 reddit 风格的投票
http://code.google.com/p/django-voting/wiki/RedditStyleVoting
回答by Matt Miller
Here's the gist of my solution. I use images with jQuery/AJAX to handle clicks. Strongly influenced by this site. There's some stuff that could use some work (error handling in the client, for example -- and much of it could probably be refactored) but hopefully the code is useful to you.
这是我的解决方案的要点。我使用带有 jQuery/AJAX 的图像来处理点击。深受本站影响。有一些东西可以使用一些工作(例如,客户端中的错误处理 - 其中大部分可能会被重构)但希望代码对您有用。
The HTML:
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 -->
The jQuery:
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);
}
});
}
});
The Django view that handles the AJAX request:
处理 AJAX 请求的 Django 视图:
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)
And the relevant parts of the Thread model:
以及 Thread 模型的相关部分:
class Thread(models.Model):
# ...
userUpVotes = models.ManyToManyField(User, blank=True, related_name='threadUpVotes')
userDownVotes = models.ManyToManyField(User, blank=True, related_name='threadDownVotes')
回答by panchicore
Whatever you do, make sure that it's submitted by POST and not GET; GET requests should neveralter database information.
无论您做什么,请确保它是通过 POST 而不是 GET 提交的;GET请求应该永远ALTER DATABASE信息。
回答by OscarRyz
As a link, button or something else?
作为链接,按钮或其他什么?
Something else, what about an image?
别的,图像呢?
When they click it, it performs the method and refreshes the page?
当他们点击它时,它会执行该方法并刷新页面?
Perhaps you could better use ajax to invoke a method to save the vote, and not refresh anything at all.
也许您可以更好地使用 ajax 来调用一个方法来保存投票,而根本不刷新任何东西。
This is what comes to my mind.
这就是我想到的。