Reputation: 141
I have a form where user enters answer for the question. If the answer is correct,user is redirected to next question.
Url pattern I follow for this is, 127.0.0.1:8000/question/1
127.0.0.1:8000/question/2 and so on.
am posting the form to the same view where the validation happens.But without form validation,user can access the subsequent url and previous url. Right now am not handling signup for a user . Any user can take up the Quiz. so in that case How do I prevent user from accessing urls directly?
I know this is a simple basic question.Am newbie in django learning by building something. Any help?.
Thanks in advance
{% extends 'base.html' %}
{% block title %}{% endblock %}
{% block body_block %}
<p><strong>Your question {{ quesno_id.id}} of {{ total_ques }}: </strong></p>
"{{ question.que }}"
<p><strong>Type your answer here :</strong></p>
<form id='song_form' method = 'post' action="">{% csrf_token %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% for field in form.visible_fields %}
{{ field.errors }}
{{ field.help_text }}
{{ field }}
{% endfor %}
<br></br>
<input type ="submit" name="submit" value="Submit"/>
</form>
{% endblock %}
def display_question(request,question_id):
context = RequestContext(request)
try:
quesno_id = {'id':question_id}
data = data.objects.get(id=question_id)
total_ques = data.objects.all().count()
except data.DoesNotExist:
pass
if request.method == 'POST':
form = que_form(request.POST)
if form.is_valid():
user_answer = form.cleaned_data['answer']
if data.name.strip() == user_answer.strip():
if int(question_id) < int(total_ques):
return HttpResponseRedirect("/question/%s/" % (int(question_id)+1))
else:
return HttpResponse('Game over')
else:
return HttpResponse("Your answer is wrong")
else:
print form.errors
else:
form = que_form()
return render_to_response('display_question.html',{'form':form,'data':data,'quesno_id':quesno_id,'total_ques':total_ques},context)
from django import forms
class que_form(forms.Form):
answer = forms.CharField(widget=forms.TextInput())
Upvotes: 0
Views: 2265
Reputation: 1361
So, a few things: 1st, I don't see you passing "question" to your template, but you call it ("question.que"). I also don't see you using "data" which you are passing. I'm assuming maybe you mean to be using data instead of question?
In any case, what you can do is something like this:
if data.name.strip() == user_answer.strip():
if int(question_id) < int(total_ques):
return render_to_response('display_question.html', {'form':form,'data':data,'quesno_id':quesno_id,'total_ques':total_ques},context)
else:
return HttpResponse('Game over')
else:
return HttpResponse("Your answer is wrong")
and you could pass the question id back and forth from the form to the view function and increment it in the view function whenever the question is answered correctly.
UPDATE:
I'm not sure if this would work re: your comment, but you could try just using javascript in display.html. Something like:
<script>
$("#text-box").val("");
</script>
My thinking would be that it would execute when you re-render to response...
Upvotes: 1
Reputation: 1459
Django includes a tool called form wizard in django.contrib.formtools
that seems to fit your need. It uses sessions/cookies in the form to validate the form pages are accessed in the correct order. You might want to look into how it works, or just use what is available without having to deal with things yourself.
If you want/need to implement this yourself, the most straightforward way is probably with sessions. Set a flag in the session when a question is answered:
request.sessions['question_{}_answered'.format(question_id)] = True
and check whether all previous questions are answered when rendering the next question. Something like...
for qid in range(1, question_id):
if 'question_{}_answered'.format(qid) not in request.sessions:
return HttpResponseRedirect('/question/1/')
# Really renders the question page
return render_to_response(...)
Upvotes: 2
Reputation: 12488
I'd serve all questions from the same URL, i.e. drop the "/" part at the end - now users can't modify the URL to get to any other question. For GET requests, you can query the database for the first unanswered question (I'm assuming you store all the answers) and display that.
Upvotes: 1