在一个简单的调查应用中,用户应该只对一组问题(调查)投票一次。我能够检查用户是否投票(懒惰用户或授权用户),但仅限于我在数据库中预填充包含测试数据的字段。我也知道懒惰的用户可以删除cookie并且可以再次投票。
我不确定如何在save()
之后拨打form.is_valid()
,因为我无法再拨两次电话。
models.py
class Vote(models.Model):
user = models.ForeignKey(User)
survey = models.ForeignKey(Survey)
vote = models.BooleanField(default=False) # not in use yet
def __unicode__(self):
return self.vote
views.py
@allow_lazy_user
def survey_detail(request, slug, template_name='survey.html'):
# allows only active surveys to be called otherwise displays HTTP 404
survey = get_object_or_404(Survey, is_active=True, slug=slug)
# checks for user id's in current survey
voter = [
v.user.id for v in Vote.objects.filter(survey=survey)
]
# checks if user already voted on survey
if request.user.id in voter:
# TODO: use different template or redirect
return render(request, 'index.html')
form = ResponseForm(request.POST or None, survey=survey)
if form.is_valid():
response = form.save(commit=False)
# gets the current user (lazy or not)
response.user = request.user
response.save()
# HOW DO I SAVE VOTER HERE?
return HttpResponseRedirect(reverse('survey:confirm', args=(slug,)))
data = {
'response_form': form,
'survey': survey
}
return render(request, template_name, data)
我的另一个想法是在模型中使用布尔字段vote
并检查模板中的True
或False
。
答案 0 :(得分:0)
好的,我用
解决了@allow_lazy_user
def survey_detail(request, slug, template_name='survey.html'):
[...]
form = ResponseForm(request.POST or None, survey=survey)
if form.is_valid():
response = form.save(commit=False)
response.user = request.user
response.save()
if not request.user.id in voter:
vote = Vote(user=request.user, survey=survey, vote=True)
vote.save()
return HttpResponseRedirect(reverse('survey:confirm', args=(slug,)))
[...]
我确信有更好的方法,但它现在有效。
答案 1 :(得分:0)
新解决方案,因为survey_id
和user_id
已经在模型Response
中:
@allow_lazy_user
def survey_detail(request, slug, template_name='itbarometer/survey_detail.html'):
# allows only active surveys to be called otherwise displays HTTP 404
survey = get_object_or_404(Survey, is_active=True, slug=slug)
categories = [c.name for c in Category.objects.filter(survey=survey)]
voter = [v.user.id for v in Response.objects.filter(survey=survey)]
# checks if survey_id and user_id are already linked
# if yes, redirect
if request.user.id in voter:
return redirect('bereits-abgeschlossen/')
form = ResponseForm(request.POST or None, survey=survey)
if form.is_valid():
response = form.save(commit=False)
# gets the current user (lazy or not)
response.user = request.user
response.save()
return HttpResponseRedirect(reverse('survey:confirm', args=(slug,)))
data = {
'response_form': form,
'survey': survey,
'categories': categories
}
return render(request, template_name, data)