def submit_answer(self, request, pk=None): """ Submit an answer to a question """ question = get_object_or_404(Question, pk=pk) self.check_object_permissions(request, question) question_history = QuestionHistory.objects.get( student=request.user, question=question ) if question_history.status == QuestionHistory.AWAITING_RESULTS: error = { 'status': False, 'detail': 'Please wait for some time' } return Response(error, status.HTTP_400_BAD_REQUEST) if question_history.status == QuestionHistory.SOLVED: error = { 'status': False, 'detail': 'Question already answered' } return Response(error, status.HTTP_400_BAD_REQUEST) if question_history.answer_shown: error = { 'status': False, 'detail': 'Correct answer already displayed' } return Response(error, status.HTTP_400_BAD_REQUEST) if question_history.attempts >= question.attempts: error = { 'status': False, 'detail': 'Exceeded the maximum number of attempts' } return Response(error, status.HTTP_400_BAD_REQUEST) question_history.attempts += 1 attempts_remaining = question.attempts - question_history.attempts serializer = serializers.AnswerSubmitSerializer(data=request.DATA) if serializer.is_valid(): # Evaluate the submission and put in the submission question_history.status = QuestionHistory.AWAITING_RESULTS submission = Submission( #course=question.course, question=question, student=request.user, grader_type=question.grader_type, answer=serializer.data['answer'] ) # Optimization: let the grader save the submission # submission.save() data = { 'status': submission.status, 'is_correct': submission.is_correct, 'result': submission.result, 'attempts_remaining': attempts_remaining } grader = Grader(submission=submission, question=question, question_history=question_history) if grader.grade(): submission = grader.submission data['status'] = submission.status data['is_correct'] = submission.is_correct data['result'] = submission.result if attempts_remaining == 0 or submission.is_correct: if grader.the_question is None: the_question = Question.objects.get_subclass( pk=submission.question.pk) data['answer'] = \ the_question.get_answer(showToUser=True) else: data['answer'] = \ grader.the_question.get_answer(showToUser=True) data['answer_description'] = question.answer_description serializer = serializers.FrontEndSubmissionSerializer(data) else: serializer = serializers.FrontEndSubmissionSerializer(data) # return the result of grading return Response(serializer.data) else: question_history.save() content = serializer.errors return Response(content, status.HTTP_400_BAD_REQUEST)
def test_quiz_history_model(self): submission = Submission.objects.get(pk=1) self.assertEqual(submission.question, Question.objects.get(pk=1)) self.assertEqual(submission.student, self.student.user) self.assertEqual(submission.answer, 'this is the answer') self.assertEqual(submission.status, 'A') grader = Grader(submission,None,None) self.assertFalse(grader.grade()) self.assertEqual(submission.status, 'A') with self.assertRaises(QuestionHistory.DoesNotExist): QuestionHistory.objects.get(student=submission.student, question=submission.question) submission = Submission.objects.get(pk=2) grader = Grader(submission,None,None) self.assertTrue(grader.grade()) self.assertEqual(submission.status, 'D') self.assertEqual(submission.is_correct, False) self.assertEqual(submission.result, 0.0) question_hist = QuestionHistory.objects.get(student=submission.student, question=submission.question) #Note : attempts not increased in grader or submission model # self.assertEqual(question_hist.attempts, 1) self.assertEqual(question_hist.status, 'O') quiz_hist = QuizHistory(user=submission.student, quiz=Quiz.objects.get(pk=1)) self.assertEqual(quiz_hist.marks, 0.0) submission = Submission.objects.get(pk=3) grader = Grader(submission,None,None) self.assertTrue(grader.grade()) self.assertEqual(submission.status, 'D') self.assertEqual(submission.is_correct, True) # marks not updated as depend on attempts # self.assertEqual(submission.result, 2.0) question_hist = QuestionHistory.objects.get(student=submission.student, question=submission.question) self.assertEqual(question_hist.status, 'S') # self.assertEqual(quiz_hist.marks, 2.0) quiz_hist = QuizHistory(user=submission.student, quiz=Quiz.objects.get(pk=1)) # self.assertEqual(quiz_hist.marks, 2.0) submission = Submission.objects.get(pk=4) grader = Grader(submission,None,None) self.assertTrue(grader.grade()) self.assertEqual(submission.is_correct, False) question_hist = QuestionHistory.objects.get(student=submission.student, question=submission.question) self.assertEqual(question_hist.status, 'O') submission = Submission.objects.get(pk=5) grader = Grader(submission,None,None) self.assertTrue(grader.grade()) self.assertEqual(submission.is_correct, True) question_hist = QuestionHistory.objects.get(student=submission.student, question=submission.question) self.assertEqual(question_hist.status, 'S') submission = Submission.objects.get(pk=6) grader = Grader(submission,None,None) self.assertTrue(grader.grade()) self.assertEqual(submission.is_correct, False) question_hist = QuestionHistory.objects.get(student=submission.student, question=submission.question) self.assertEqual(question_hist.status, 'O') submission = Submission.objects.get(pk=7) grader = Grader(submission,None,None) self.assertTrue(grader.grade()) self.assertEqual(submission.is_correct, True) question_hist = QuestionHistory.objects.get(student=submission.student, question=submission.question) self.assertEqual(question_hist.status, 'S')