我正在创建一个使用Django的论坛。我有很多工作要做,包括投票。我唯一搞不懂的就是防止重复投票。我怎么才能让这个起作用?有没有一种方法可以用JS制作一个HTML表单,只能发送一次?还是我要在视野里做一些特殊的手术?下面是模板中的代码:
{% for comment in comments %}
<div class="ui container segment">
<img class="ui avatar image" src="/{{ comment.by.userprofile.img.url }}"><b>{{ comment.by }}</b>
<p style="font-size: 20px">{{ comment.body }}</p>
<form action="" method="post">
{% csrf_token %}
<input type="submit" value="Thumbs up" class="ui small blue button">
<i class="thumbs up outline icon"></i>
<input type="hidden" value="{{ comment.id }}" name="comment">
</form>
<span>{{ comment.points }}</span>
</div>
{% endfor %}我在视图中的代码:
elif request.method == 'POST':
print request.POST
if 'body' in request.POST.keys():
reply = ForumReply.objects.create(by=request.user, reply_to=post, body=request.POST['body'])
reply.save()
notification = Notification.objects.create(to=post.by, message='Your post "' + post.title + '" received a new reply')
notification.save()
if 'comment' in request.POST.keys():
comment = post.forumreply_set.filter(pk=request.POST['comment'])[0]
comment.points += 1
comment.save()和我的模型(根据乐高风暴部队的要求)
class ForumReply(models.Model):
by = models.ForeignKey(User)
reply_to = models.ForeignKey(ForumPost)
body = models.TextField()
created = models.DateField(default=timezone.now())
points = models.IntegerField(default=0)发布于 2015-12-14 13:10:59
好吧,我找到了解决问题的办法,但我肯定这不是最优雅的。然而,它的工作,因为我需要它。
所以,我所做的就是在ManyToManyField上创建一个UserProfile。所有用户都与OneToOne有一个UserProfile关系。
class UserProfile(models.Model):
user = models.OneToOneField(User)
bio = models.TextField(default='This user hasn\'t said anything about themselves yet')
img = models.ImageField(upload_to=gen_name, default="static/imgs/default/default_user.jpg")
points = models.IntegerField(default=0)
liked_replies = models.ManyToManyField(ForumReply)每当用户喜欢一个回复时,它就会保存到那个ManyToManyField中。然后,在视图中,它检查该评论是否在当前用户喜欢的回复列表中,如果是的话,它不会添加投票。
if 'comment' in request.POST.keys():
comment = post.forumreply_set.filter(pk=request.POST['comment'])[0]
if not comment in request.user.userprofile.liked_replies.all():
print 'liked'
comment.points += 1
comment.save()
request.user.userprofile.liked_replies.add(comment)
request.user.userprofile.save()发布于 2015-12-14 04:10:17
您肯定希望防止在服务器上进行双重投票,而不是在javascript中。否则,有人可能会编写恶意脚本来破坏您的投票系统数据库。有几个解决方案,让我们从最简单的开始:
1)在服务器上,您需要检查用户以前是否投票。添加如下内容:
voted_before = len(ForumReply.objects.filter(by=request.user, reply_to=post)[:1]) > 1
然后,在添加新的选票之前,可以检查voted_before是否为True。
2)然而,第一个解决方案受种族条件的影响。如果一个用户simultaneously进行两次相同的投票,服务器可能不会检测到它以前投过票。
为了避免争用条件,您只使用一台服务器,并且只有一个django进程正在运行,您可以使用threading.Lock来防止检查多次发生。
3)如果使用多个服务器和分布式数据库,则需要使用称为事务的东西。这些通常是特定于数据库的。
https://stackoverflow.com/questions/34259520
复制相似问题