当我提交表单时,视图函数内的问题 id 与 request.POST 中的问题 id 不匹配。
提交from时,下面视图函数的打印语句为:
问题_4 问题_5
在 request.POST 中,id 是 15 和 17,在视图中是 4、5。 每次我提交表单时,ID 都不匹配。
查看:
@login_required
def quiz_view(request):
questions = QuizQuestion.objects.order_by('?')[:2]
user = request.user
if request.method == 'POST':
print(request.POST)
for question in questions:
input_name = f"question_{question.id}"
print(input_name)
option_selected = request.POST.get(input_name)
if option_selected:
# Check if the user has already responded to this question
existing_response = QuizUserResponse.objects.filter(user=user, question=question).first()
if existing_response:
# Update existing response
existing_response.response_text = getattr(question, option_selected)
existing_response.save()
else:
# Create new response
QuizUserResponse.objects.create(user=user, question=question, response_text=getattr(question, option_selected))
return redirect('users:gaming_quiz')
else:
context = {
"questions": questions,
}
return render(request, 'general/quiz_template.html', context)
HTML:
<form method="post">
{% csrf_token %}
{% for question in questions %}
<div>
<label class="question">{{ question.question_text }}</label>
<ul class="errors">
{% for error in form.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
<div>
<label class="form-check-inline">
<input type="radio" name="question_{{ question.id }}" value="option1"> {{ question.option1 }}
</label>
<label class="form-check-inline">
<input type="radio" name="question_{{ question.id }}" value="option2"> {{ question.option2 }}
</label>
<label class="form-check-inline">
<input type="radio" name="question_{{ question.id }}" value="option3"> {{ question.option3 }}
</label>
<label class="form-check-inline">
<input type="radio" name="question_{{ question.id }}" value="option4"> {{ question.option4 }}
</label>
</div>
</div>
{% endfor %}
<button type="submit">Submit</button>
</form>
这并不奇怪,你再次提交到视图,在那里你再次从数据库中查询两个随机
QuizQuestion
,但不能保证这些与GET请求相同,在事实上,这种情况发生的可能性非常。
因此,如果发出 POST 请求,您应该获取 id 出现在
QuizQuestion
中的 request.POST
,所以相反的方式:
@login_required
def quiz_view(request):
user = request.user
if request.method == 'POST':
question_ids = [
key[9:] for key in request.POST if key.startswith('question_')
]
questions = QuizQuestion.objects.filter(pk__in=question_ids)
for question in questions:
input_name = f"question_{question.id}"
print(input_name)
option_selected = request.POST.get(input_name)
if option_selected:
existing_response = QuizUserResponse.objects.filter(
user=user, question=question
).first()
if existing_response:
# Update existing response
existing_response.response_text = getattr(
question, option_selected
)
existing_response.save()
else:
# Create new response
QuizUserResponse.objects.create(
user=user,
question=question,
response_text=getattr(question, option_selected),
)
return redirect('users:gaming_quiz')
else:
questions = QuizQuestion.objects.order_by('?')[:2]
context = {
'questions': questions,
}
return render(request, 'general/quiz_template.html', context)
[python-doc] 使用属性的任意(用户指定)值通常(非常)不安全:它允许用户获取您想要的敏感数据隐藏。您可能想检查如何限制选项以提高安全性。getattr(…)