Django 使用身份验证进行轮询

Posted

技术标签:

【中文标题】Django 使用身份验证进行轮询【英文标题】:Django polls with autentication 【发布时间】:2018-03-03 02:16:15 【问题描述】:

我有一个使用文档中的 django 的投票应用程序。我现在想让它先进。我不希望用户能够投票两次,这意味着用户只能投票一次,否则会显示错误消息。如果是超级用户登录,它可以正常工作,但对于任何其他用户,他们仍然可以多次投票。

型号

class Question(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL,related_name='question_created')
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')

    def __str__(self):
        return self.question_text


class Choice(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL,related_name='choice_created')
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

    def __str__(self):
        return self.choice_text

查看

def vote(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    if Choice.objects.filter(question_id=question_id, user_id=request.user.id).exists():
        context = 
                'question': question,
                'error_message': "Sorry, but you have already voted.",
                
        template = 'polls/detail.html'
        return render(request, template, context)
    try:
        selected_choice = question.choice_set.get(pk=request.POST['choice'])
    except (KeyError, Choice.DoesNotExist):
        context = 
                'question': question,
                'error_message': "You didn't select a choice.",
                
        template = 'polls/detail.html'
        return render(request, template, context)
    else:
        selected_choice.votes += 1
        selected_choice.save()
        return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))

【问题讨论】:

您想通过try..except..else 语句实现什么目标? 这样用户就不能提交空表单 我特别提到了else块,为什么它是try..except的一部分? 用户投票后,投票数加一 我认为您可以简单地在def 块中编写selected_choice.votes += 1 和该缩进级别的代码,而不是else 块。仅当他的try 语句成功时才会执行,因为如果不成功,您将在except 语句中返回。你可以试试吗? 【参考方案1】:

首先,您的 try 块不会按预期工作,因为如果选择为空,question.choice_set.get 不会引发异常,只会返回 None。 您可以使用 if 条件,例如:

 if selected_choice is None:

对于您的主要问题,您应该防止未经身份验证的用户出现在您的视图中,例如:

if not request.user.is_authenticated:

【讨论】:

【参考方案2】:

尝试将try: Except: 移动到else: 语句中。

在“question_id”和“user_id”中添加 2 个下划线,就像这样 Choice.objects.filter(question__id=question_id, user__id=request.user.id).exists() 可能这就是为什么 if 语句每次都返回 false 并且它可以让你投票两次

同样为了安全起见,您可以将selected_choice.votes += 1 更改为selected_choice.votes = 1 以确保每条记录不超过一票。

希望对您有所帮助!

【讨论】:

question__id 和 user__id 不是必需的。大多数情况下,在表本身中使用保存的相关 id 会更好。

以上是关于Django 使用身份验证进行轮询的主要内容,如果未能解决你的问题,请参考以下文章

在 Django 中使用 JWT 进行身份验证

使用 Django 通道进行会话身份验证

使用多个数据库进行 Django 身份验证

使用 Django Rest 框架进行 JWT 令牌身份验证

django REST facebook 身份验证

没有密码的django身份验证