From e44bd4577bf839148c0824a9d3cc84a789f25b95 Mon Sep 17 00:00:00 2001 From: prathamesh Date: Mon, 11 Aug 2014 13:00:33 +0530 Subject: redirect to dashboard after exam. After exam is over or time-out the user is redirected to the result page. The user is not logged out. Current time is checked with the quiz end time, so that the user cannot reattempt the quiz. --- testapp/exam/views.py | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) (limited to 'testapp/exam/views.py') diff --git a/testapp/exam/views.py b/testapp/exam/views.py index 7c9af6c..aeb93ca 100644 --- a/testapp/exam/views.py +++ b/testapp/exam/views.py @@ -22,6 +22,7 @@ from exam.forms import UserRegisterForm, UserLoginForm, QuizForm,\ from exam.xmlrpc_clients import code_server from settings import URL_ROOT + # The directory where user data can be saved. OUTPUT_DIR = abspath(join(dirname(__file__), 'output')) @@ -142,7 +143,6 @@ def quizlist_user(request): pre_requisites = [] context = {} - if 'cannot_attempt' in request.GET: context['cannot_attempt'] = True @@ -155,7 +155,7 @@ def quizlist_user(request): for answer_paper in user_answerpapers: for quiz in avail_quizzes: if answer_paper.question_paper.id == quiz.id and \ - answer_paper.end_time != answer_paper.start_time: + answer_paper.end_time != answer_paper.start_time: avail_quizzes.remove(quiz) quizzes_taken.append(answer_paper) @@ -181,11 +181,11 @@ def intro(request, questionpaper_id): return my_render_to_response('exam/intro.html', context, context_instance=ci) else: - context = {'user': user, 'cannot_attempt':True} + context = {'user': user, 'cannot_attempt': True} return my_redirect("/exam/quizzes/?cannot_attempt=True") except: - context = {'user': user, 'cannot_attempt':True} + context = {'user': user, 'cannot_attempt': True} return my_redirect("/exam/quizzes/?cannot_attempt=True") context = {'user': user, 'paper_id': questionpaper_id} ci = RequestContext(request) @@ -389,7 +389,7 @@ def add_quiz(request, quiz_id=None): form.initial['active'] = d.active form.initial['pass_criteria'] = d.pass_criteria form.initial['language'] = d.language - form.initial['prerequisite'] = d.prerequisite_id + form.initial['prerequisite'] = d.prerequisite_id return my_render_to_response('exam/add_quiz.html', {'form': form}, context_instance=ci) @@ -607,10 +607,11 @@ rights/permissions and log in.""" users_failed = AnswerPaper.objects.filter(question_paper=paper, passed=False).count() temp = paper, answer_papers, users_passed, users_failed users_per_paper.append(temp) - context = {'user': user, 'users_per_paper':users_per_paper} + context = {'user': user, 'users_per_paper': users_per_paper} return my_render_to_response('manage.html', context) return my_redirect('/exam/login/') + def user_login(request): """Take the credentials of the user and log the user in.""" @@ -691,6 +692,9 @@ def question(request, q_id, questionpaper_id, success_msg=None): if not paper.question_paper.quiz.active: reason = 'The quiz has been deactivated!' return complete(request, reason, questionpaper_id) + elif paper.end_time < datetime.datetime.now(): + reason = 'You have already attempted the quiz' + return complete(request, reason, questionpaper_id) time_left = paper.time_left() if time_left == 0: return complete(request, reason='Your time is up!') @@ -722,11 +726,11 @@ def check(request, q_id, questionpaper_id=None): """Checks the answers of the user for particular question""" user = request.user - if not user.is_authenticated(): - return my_redirect('/exam/login/') - question = get_object_or_404(Question, pk=q_id) q_paper = QuestionPaper.objects.get(id=questionpaper_id) paper = AnswerPaper.objects.get(user=request.user, question_paper=q_paper) + if not user.is_authenticated() or paper.end_time < datetime.datetime.now(): + return my_redirect('/exam/login/') + question = get_object_or_404(Question, pk=q_id) snippet_code = request.POST.get('snippet') skip = request.POST.get('skip', None) success_msg = False @@ -816,7 +820,7 @@ def validate_answer(user, user_answer, question): success, message = code_server.run_code(user_answer, question.test, user_dir, question.language) if success: - correct = True + correct = True return correct, success, message @@ -842,6 +846,7 @@ def complete(request, reason=None, questionpaper_id=None): paper.update_marks_obtained() paper.update_percent() paper.update_passed() + paper.end_time = datetime.datetime.now() paper.save() obt_marks = paper.marks_obtained tot_marks = paper.question_paper.total_marks @@ -850,12 +855,10 @@ def complete(request, reason=None, questionpaper_id=None): you answered all the questions correctly.\ You have been logged out successfully,\ Thank You !"} - logout(request) return my_render_to_response('exam/complete.html', context) else: message = reason or "You are successfully logged out" context = {'message': message} - logout(request) return my_render_to_response('exam/complete.html', context) no = False message = reason or 'The quiz has been completed. Thank you.' @@ -866,7 +869,7 @@ def complete(request, reason=None, questionpaper_id=None): if not no: # Logout the user and quit with the message given. answer_paper = AnswerPaper.objects.get(id=answerpaper_id) - answer_paper.endtime = datetime.datetime.now() + answer_paper.end_time = datetime.datetime.now() answer_paper.save() return my_redirect('/exam/quizzes/') else: @@ -1118,8 +1121,8 @@ def ajax_questionpaper(request, query): question_list = fixed_question_list + random_question_list questions = list(Question.objects.filter(type=question_type, points=marks_selected)) - questions = [ question for question in questions \ - if not str(question.id) in question_list ] + questions = [question for question in questions \ + if not str(question.id) in question_list] return my_render_to_response('exam/ajax_questions.html', {'questions': questions}) @@ -1147,7 +1150,7 @@ def design_questionpaper(request): question_paper.save() if fixed_questions: fixed_questions_ids = ",".join(fixed_questions) - fixed_questions_ids_list = fixed_questions_ids.split(',') + fixed_questions_ids_list = fixed_questions_ids.split(',') for question_id in fixed_questions_ids_list: question_paper.fixed_questions.add(question_id) if random_questions: -- cgit From 0808861705c08aede6c0dc9e07ac891911a7bbfb Mon Sep 17 00:00:00 2001 From: prathamesh Date: Tue, 23 Sep 2014 14:44:47 +0530 Subject: Models and views modified. Added number of attempts option for quiz. Also days lag between two attempts. added test status and attempt number for the test. Removed profile foreign key from answer paper models since user foreign key is present in the answer paper model. Urls slightly modified to include attemt number for a given quiz. --- testapp/exam/views.py | 107 +++++++++++++++++++++++++++++--------------------- 1 file changed, 63 insertions(+), 44 deletions(-) (limited to 'testapp/exam/views.py') diff --git a/testapp/exam/views.py b/testapp/exam/views.py index aeb93ca..44884fd 100644 --- a/testapp/exam/views.py +++ b/testapp/exam/views.py @@ -139,7 +139,7 @@ def quizlist_user(request): user = request.user avail_quizzes = list(QuestionPaper.objects.filter(quiz__active=True)) user_answerpapers = AnswerPaper.objects.filter(user=user) - quizzes_taken = [] + quizzes_taken = user_answerpapers pre_requisites = [] context = {} @@ -152,13 +152,6 @@ def quizlist_user(request): context['quizzes_taken'] = None return my_render_to_response("exam/quizzes_user.html", context) - for answer_paper in user_answerpapers: - for quiz in avail_quizzes: - if answer_paper.question_paper.id == quiz.id and \ - answer_paper.end_time != answer_paper.start_time: - avail_quizzes.remove(quiz) - quizzes_taken.append(answer_paper) - context['quizzes'] = avail_quizzes context['user'] = user context['quizzes_taken'] = quizzes_taken @@ -170,27 +163,45 @@ def intro(request, questionpaper_id): user = request.user ci = RequestContext(request) quest_paper = QuestionPaper.objects.get(id=questionpaper_id) + attempt_number = quest_paper.quiz.attempts_allowed + time_lag = quest_paper.quiz.time_between_attempts + if quest_paper.quiz.prerequisite: try: - pre_quest = QuestionPaper.objects.get(quiz=quest_paper.quiz.prerequisite) - answer_paper = AnswerPaper.objects.get( - question_paper=pre_quest, - user=user) - if answer_paper.passed: - context = {'user': user, 'paper_id': questionpaper_id} - return my_render_to_response('exam/intro.html', context, - context_instance=ci) - else: + pre_quest = QuestionPaper.objects.get( + quiz=quest_paper.quiz.prerequisite) + answer_papers = AnswerPaper.objects.filter( + question_paper=pre_quest, user=user) + answer_papers_failed = AnswerPaper.objects.filter( + question_paper=pre_quest, user=user, passed=False) + if answer_papers.count() == answer_papers_failed.count(): context = {'user': user, 'cannot_attempt': True} return my_redirect("/exam/quizzes/?cannot_attempt=True") - except: context = {'user': user, 'cannot_attempt': True} return my_redirect("/exam/quizzes/?cannot_attempt=True") - context = {'user': user, 'paper_id': questionpaper_id} - ci = RequestContext(request) - return my_render_to_response('exam/intro.html', context, - context_instance=ci) + + attempted_papers = AnswerPaper.objects.filter(question_paper=quest_paper, + user=user) + already_attempted = attempted_papers.count() + if already_attempted == 0: + context = {'user': user, 'paper_id': questionpaper_id,\ + 'attempt_no': already_attempted + 1} + return my_render_to_response('exam/intro.html', context, + context_instance=ci) + if already_attempted < attempt_number: + previous_attempt_day = attempted_papers[already_attempted-1].start_time + today = datetime.datetime.today() + days_after_attempt = (today - previous_attempt_day).days + if days_after_attempt >= time_lag: + context = {'user': user, 'paper_id': questionpaper_id,\ + 'attempt_no': already_attempted + 1} + return my_render_to_response('exam/intro.html', context, + context_instance=ci) + else: + return my_redirect("/exam/quizzes/") + else: + return my_redirect("/exam/quizzes/") def results_user(request): @@ -367,6 +378,8 @@ def add_quiz(request, quiz_id=None): d.pass_criteria = form['pass_criteria'].data d.language = form['language'].data d.prerequisite_id = form['prerequisite'].data + d.attempts_allowed = form['attempts_allowed'].data + d.time_between_attempts = form['time_between_attempts'].data d.save() quiz = Quiz.objects.get(id=quiz_id) return my_redirect("/exam/manage/showquiz") @@ -390,6 +403,8 @@ def add_quiz(request, quiz_id=None): form.initial['pass_criteria'] = d.pass_criteria form.initial['language'] = d.language form.initial['prerequisite'] = d.prerequisite_id + form.initial['attempts_allowed'] = d.attempts_allowed + form.initial['time_between_attempts'] = d.time_between_attempts return my_render_to_response('exam/add_quiz.html', {'form': form}, context_instance=ci) @@ -641,7 +656,7 @@ def user_login(request): context_instance=ci) -def start(request, questionpaper_id=None): +def start(request, attempt_no=None, questionpaper_id=None): """Check the user cedentials and if any quiz is available, start the exam.""" user = request.user @@ -654,13 +669,13 @@ def start(request, questionpaper_id=None): except QuestionPaper.DoesNotExist: msg = 'Quiz not found, please contact your '\ 'instructor/administrator. Please login again thereafter.' - return complete(request, msg, questionpaper_id) + return complete(request, msg, attempt_no, questionpaper_id) try: old_paper = AnswerPaper.objects.get( - question_paper=questionpaper, user=user) + question_paper=questionpaper, user=user, attempt_number=attempt_no) q = old_paper.current_question() - return show_question(request, q, questionpaper_id) + return show_question(request, q, attempt_no, questionpaper_id) except AnswerPaper.DoesNotExist: ip = request.META['REMOTE_ADDR'] key = gen_key(10) @@ -670,13 +685,13 @@ def start(request, questionpaper_id=None): msg = 'You do not have a profile and cannot take the quiz!' raise Http404(msg) - new_paper = questionpaper.make_answerpaper(user, ip,) + new_paper = questionpaper.make_answerpaper(user, ip, attempt_no) # Make user directory. user_dir = get_user_dir(user) - return start(request, questionpaper_id) + return start(request, attempt_no, questionpaper_id) -def question(request, q_id, questionpaper_id, success_msg=None): +def question(request, q_id, attempt_no, questionpaper_id, success_msg=None): """Check the credentials of the user and start the exam.""" user = request.user @@ -686,7 +701,7 @@ def question(request, q_id, questionpaper_id, success_msg=None): try: q_paper = QuestionPaper.objects.get(id=questionpaper_id) paper = AnswerPaper.objects.get( - user=request.user, question_paper=q_paper) + user=request.user, attempt_number=attempt_no, question_paper=q_paper) except AnswerPaper.DoesNotExist: return my_redirect('/exam/start/') if not paper.question_paper.quiz.active: @@ -713,21 +728,22 @@ def question(request, q_id, questionpaper_id, success_msg=None): context_instance=ci) -def show_question(request, q_id, questionpaper_id, success_msg=None): +def show_question(request, q_id, attempt_no, questionpaper_id, success_msg=None): """Show a question if possible.""" if len(q_id) == 0: msg = 'Congratulations! You have successfully completed the quiz.' - return complete(request, msg, questionpaper_id) + return complete(request, msg, attempt_no, questionpaper_id) else: - return question(request, q_id, questionpaper_id, success_msg) + return question(request, q_id, attempt_no, questionpaper_id, success_msg) -def check(request, q_id, questionpaper_id=None): +def check(request, q_id, attempt_no=None, questionpaper_id=None): """Checks the answers of the user for particular question""" user = request.user q_paper = QuestionPaper.objects.get(id=questionpaper_id) - paper = AnswerPaper.objects.get(user=request.user, question_paper=q_paper) + paper = AnswerPaper.objects.get(user=request.user, attempt_number=attempt_no, + question_paper=q_paper) if not user.is_authenticated() or paper.end_time < datetime.datetime.now(): return my_redirect('/exam/login/') question = get_object_or_404(Question, pk=q_id) @@ -737,7 +753,7 @@ def check(request, q_id, questionpaper_id=None): success = True if skip is not None: next_q = paper.skip() - return show_question(request, next_q, questionpaper_id) + return show_question(request, next_q, attempt_no, questionpaper_id) # Add the answer submitted, regardless of it being correct or not. if question.type == 'mcq': @@ -770,10 +786,10 @@ def check(request, q_id, questionpaper_id=None): if not success: # Should only happen for non-mcq questions. if time_left == 0: reason = 'Your time is up!' - return complete(request, reason, questionpaper_id) + return complete(request, reason, attempt_no, questionpaper_id) if not paper.question_paper.quiz.active: reason = 'The quiz has been deactivated!' - return complete(request, reason, questionpaper_id) + return complete(request, reason, attempt_no, questionpaper_id) context = {'question': question, 'error_message': err_msg, 'paper': paper, 'last_attempt': user_code, 'quiz_name': paper.question_paper.quiz.description, @@ -785,10 +801,10 @@ def check(request, q_id, questionpaper_id=None): else: if time_left <= 0: reason = 'Your time is up!' - return complete(request, reason, questionpaper_id) + return complete(request, reason, attempt_no, questionpaper_id) else: next_q = paper.completed_question(question.id) - return show_question(request, next_q, + return show_question(request, next_q, attempt_no, questionpaper_id, success_msg) @@ -824,14 +840,15 @@ def validate_answer(user, user_answer, question): return correct, success, message -def quit(request, questionpaper_id=None): +def quit(request, attempt_no=None, questionpaper_id=None): """Show the quit page when the user logs out.""" - context = {'id': questionpaper_id} + context = {'id': questionpaper_id, + 'attempt_no': attempt_no} return my_render_to_response('exam/quit.html', context, context_instance=RequestContext(request)) -def complete(request, reason=None, questionpaper_id=None): +def complete(request, reason=None, attempt_no=None, questionpaper_id=None): """Show a page to inform user that the quiz has been compeleted.""" user = request.user @@ -842,11 +859,13 @@ def complete(request, reason=None, questionpaper_id=None): return my_render_to_response('exam/complete.html', context) else: q_paper = QuestionPaper.objects.get(id=questionpaper_id) - paper = AnswerPaper.objects.get(user=user, question_paper=q_paper) + paper = AnswerPaper.objects.get(user=user, question_paper=q_paper, + attempt_number=attempt_no) paper.update_marks_obtained() paper.update_percent() paper.update_passed() paper.end_time = datetime.datetime.now() + paper.update_status() paper.save() obt_marks = paper.marks_obtained tot_marks = paper.question_paper.total_marks -- cgit