【问题标题】:How to restrict anonymous users to vote only once in django poll app?如何限制匿名用户在 django poll 应用程序中只投票一次?
【发布时间】:2021-03-18 18:35:42
【问题描述】:

我想限制每个用户在我的投票应用程序中只能为一个问题投票一次。对于经过身份验证的用户,我的代码运行良好,但是当匿名用户(未注册)尝试投票时,我得到了下一个错误:

TypeError: 'AnonymousUser' 对象不可迭代

如何限制匿名用户只能投票一次?

你可以在这里看到我的相关代码:

models.py:

class Question(models.Model):
    question_text = models.TextField("Question", max_length=300)
    category = models.CharField(max_length=100)
    pupblish_date = models.DateTimeField(default=now)
    author = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        return self.question_text

class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField("Choice",max_length=200)
    votes = models.IntegerField(default=0)

    def __str__(self):
        return self.choice_text

class Vote(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    voter = models.ForeignKey(User, on_delete=models.CASCADE)

views.py:

def vote_view(request, poll_id):
    poll = get_object_or_404(Question, pk=poll_id)
    if Vote.objects.filter(question=poll, voter=request.user).exists():
        messages.error(request,"Already Voted on this choice")
        return redirect("poll_app:home")
    else:
        if request.method == "POST":
            try:
                selected_choice = poll.choice_set.get(pk=request.POST["clap"])    
            except(KeyError):
                return render(request, "poll_app/vote.html", {
                    "poll": poll, 
                    "error_message": "You haven't voted yet!"
                    })
            else:
                selected_choice.votes += 1
                selected_choice.save()
                Vote.objects.create(voter = request.user, question=poll)
                return redirect(reverse("poll_app:result", args=(poll.id,)))
        else:
            context = {"poll": poll}
            return render(request, "poll_app/vote.html", context)

谢谢!

【问题讨论】:

  • 您需要某种机制来将用户识别为唯一的。 IP 地址是不够的,因为它可以被伪造。也许您可以使用指纹 JS 库来唯一地识别用户。

标签: django django-models django-views django-authentication django-users


【解决方案1】:

前段时间我做了同样的事情来防止同一个ip多次投票。

你可以在你的models.py中使用这个类来存储传入的ip:

class VoterIp(models.Model):
    post = models.ForeignKey(Post,on_delete=models.CASCADE,related_name='ips',null=True)
    ip = models.CharField(max_length=100)

    def __str__(self):
        return self.ip

在你的views.py文件中你可以做这样的逻辑:

def positive_post(request,post_id):
    # Getting Ip
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[0]
    else:
        ip = request.META.get('REMOTE_ADDR')

    obj = Comment.objects.get(pk=post_id)
    # try to get the object in DB, if you can, it means IP has 
    # already voted
    try:
        obj1 = VoterIp.objects.get(post_id=obj.id,ip=ip)
        
        return HttpResponse('<h1> YOU ALREADY VOTED!! </h1>')
    # If you can not, then create new entry for the new ip vote.
    except:
        
        new_ip = VoterIp()
        new_ip.post = obj
        new_ip.ip = ip
        new_ip.save()
        # Now sum one vote in the positive side
        obj.post_pos += 1
        obj.save()
        
       
    return redirect("some_place")

您可以对否定 ip voter 使用相同的逻辑函数。

【讨论】:

    猜你喜欢
    • 2019-06-07
    • 1970-01-01
    • 2010-10-06
    • 1970-01-01
    • 2012-03-15
    • 1970-01-01
    • 2011-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多