+ {% if paper.quiz.prerequisite %}
+ You have to pass {{ paper.quiz.prerequisite.description }} for taking {{ paper.quiz.description }}
+ {% else %}
+ No pre requisites for {{ paper.quiz.description }}
+ {% endif %}
+
+
+ {% endif %}
+ {% endfor %}
+
{% endif %}
+
+
+
+
+{% endfor %}
+
+
List of quizzes taken by you so far
+{% if quizzes_taken %}
+
+
Quiz
+
Result
+
Marks Obtained
+
Total Marks
+
Percentage
+ {% for paper in quizzes_taken %}
+
- {% if paper.quiz.prerequisite %}
- You have to pass {{ paper.quiz.prerequisite.description }} for taking {{ paper.quiz.description }}
+ {{ paper.question_paper.quiz.description }}
+
+
+ {% if paper.passed %}
+
Pass
{% else %}
- No pre requisites for {{ paper.quiz.description }}
+
Fail
{% endif %}
+
+ {{ paper.marks_obtained }}
+
+
+ {{ paper.question_paper.total_marks }}
+
+
+ {{ paper.percent }}
+
{% endfor %}
-
-
List of quizzes taken by you so far
- {% if quizzes_taken %}
-
-
Quiz
-
Result
-
Marks Obtained
-
Total Marks
-
Percentage
- {% for paper in quizzes_taken %}
-
-
- {{ paper.question_paper.quiz.description }}
-
-
- {% if paper.passed %}
-
Pass
- {% else %}
-
Fail
- {% endif %}
-
-
- {{ paper.marks_obtained }}
-
-
- {{ paper.question_paper.total_marks }}
-
-
- {{ paper.percent }}
-
-
- {% endfor %}
-
- {% else %}
-
You have not taken any quiz yet !!
- {% endif %}
+{% else %}
+
You have not taken any quiz yet !!
+{% endif %}
{% endblock %}
diff --git a/yaksh/urls.py b/yaksh/urls.py
index e6c2e15..ad0a925 100644
--- a/yaksh/urls.py
+++ b/yaksh/urls.py
@@ -19,6 +19,8 @@ urlpatterns = patterns('yaksh.views',
'check'),
url(r'^intro/$', 'start'),
url(r'^(?P\d+)/(?P\d+)/(?P\d+)/$', 'show_question'),
+ url(r'^enroll_request/(?P\d+)/$', 'enroll_request'),
+ url(r'^self_enroll/(?P\d+)/$', 'self_enroll'),
url(r'^manage/$', 'prof_manage'),
url(r'^manage/addquestion/$', 'add_question'),
@@ -54,6 +56,16 @@ urlpatterns = patterns('yaksh.views',
'show_statistics'),
url(r'^manage/statistics/question/(?P\d+)/(?P\d+)/$',
'show_statistics'),
+ url(r'manage/courses/$', 'courses'),
+ url(r'manage/add_course/$', 'add_course'),
+ url(r'manage/course_detail/(?P\d+)/$', 'course_detail'),
+ url(r'manage/enroll/(?P\d+)/(?P\d+)/$', 'enroll'),
+ url(r'manage/enroll/rejected/(?P\d+)/(?P\d+)/$',
+ 'enroll', {'was_rejected': True}),
+ url(r'manage/reject/(?P\d+)/(?P\d+)/$', 'reject'),
+ url(r'manage/enrolled/reject/(?P\d+)/(?P\d+)/$',
+ 'reject', {'was_enrolled': True}),
+ url(r'manage/toggle_status/(?P\d+)/$', 'toggle_course_status'),
url(r'^ajax/questionpaper/(?P.+)/$', 'ajax_questionpaper'),
url(r'^ajax/questions/filter/$', 'ajax_questions_filter'),
diff --git a/yaksh/views.py b/yaksh/views.py
index 6558427..9540a06 100644
--- a/yaksh/views.py
+++ b/yaksh/views.py
@@ -17,11 +17,11 @@ from taggit.models import Tag
from itertools import chain
import json
# Local imports.
-from yaksh.models import Quiz, Question, QuestionPaper, QuestionSet
+from yaksh.models import Quiz, Question, QuestionPaper, QuestionSet, Course
from yaksh.models import Profile, Answer, AnswerPaper, User, TestCase
from yaksh.forms import UserRegisterForm, UserLoginForm, QuizForm,\
QuestionForm, RandomQuestionForm, TestCaseFormSet,\
- QuestionFilterForm
+ QuestionFilterForm, CourseForm
from yaksh.xmlrpc_clients import code_server
from settings import URL_ROOT
from yaksh.models import AssignmentUpload
@@ -157,6 +157,8 @@ def quizlist_user(request):
disabled_quizzes = []
unexpired_quizzes = []
+ courses = Course.objects.filter(active=True)
+
for paper in avail_quizzes:
quiz_enable_time = paper.quiz.start_date_time
quiz_disable_time = paper.quiz.end_date_time
@@ -170,7 +172,8 @@ def quizlist_user(request):
'quizzes': avail_quizzes,
'user': user,
'quizzes_taken': quizzes_taken,
- 'unexpired_quizzes': unexpired_quizzes
+ 'unexpired_quizzes': unexpired_quizzes,
+ 'courses': courses
}
return my_render_to_response("yaksh/quizzes_user.html", context)
@@ -495,7 +498,7 @@ def add_quiz(request, quiz_id=None):
if not user.is_authenticated() or not is_moderator(user):
raise Http404('You are not allowed to view this page!')
if request.method == "POST":
- form = QuizForm(request.POST)
+ form = QuizForm(request.POST, user=user)
if form.is_valid():
data = form.cleaned_data
if quiz_id is None:
@@ -527,13 +530,13 @@ def add_quiz(request, quiz_id=None):
context_instance=ci)
else:
if quiz_id is None:
- form = QuizForm()
+ form = QuizForm(user=user)
return my_render_to_response('yaksh/add_quiz.html',
{'form': form},
context_instance=ci)
else:
d = Quiz.objects.get(id=quiz_id)
- form = QuizForm()
+ form = QuizForm(user=user)
form.initial['start_date'] = d.start_date_time.date()
form.initial['start_time'] = d.start_date_time.time()
form.initial['end_date'] = d.end_date_time.date()
@@ -759,7 +762,7 @@ def prof_manage(request):
rights/permissions and log in."""
user = request.user
if user.is_authenticated() and is_moderator(user):
- question_papers = QuestionPaper.objects.all()
+ question_papers = QuestionPaper.objects.filter(quiz__course__creator=user)
users_per_paper = []
for paper in question_papers:
answer_papers = AnswerPaper.objects.filter(question_paper=paper)
@@ -1165,6 +1168,102 @@ def complete(request, reason=None, attempt_num=None, questionpaper_id=None):
return my_redirect('/exam/')
+@login_required
+def add_course(request):
+ user = request.user
+ ci = RequestContext(request)
+ if not is_moderator(user):
+ raise Http404('You are not allowed to view this page')
+ if request.method == 'POST':
+ form = CourseForm(request.POST)
+ if form.is_valid():
+ new_course = form.save(commit=False)
+ new_course.creator = user
+ new_course.save()
+ return my_render_to_response('manage.html', {'course': new_course})
+ else:
+ return my_render_to_response('yaksh/add_course.html',
+ {'form': form},
+ context_instance=ci)
+ else:
+ form = CourseForm()
+ return my_render_to_response('yaksh/add_course.html', {'form': form},
+ context_instance=ci)
+
+
+@login_required
+def enroll_request(request, course_id):
+ user = request.user
+ ci = RequestContext(request)
+ course = get_object_or_404(Course, pk=course_id)
+ course.request(user)
+ return my_redirect('/exam/manage/')
+
+
+@login_required
+def self_enroll(request, course_id):
+ user = request.user
+ ci = RequestContext(request)
+ course = get_object_or_404(Course, pk=course_id)
+ if course.is_self_enroll():
+ course.enroll(False, user)
+ return my_redirect('/exam/manage/')
+
+
+@login_required
+def courses(request):
+ user = request.user
+ if not is_moderator(user):
+ raise Http404('You are not allowed to view this page')
+ courses = Course.objects.filter(creator=user)
+ return my_render_to_response('yaksh/courses.html', {'courses': courses})
+
+
+@login_required
+def course_detail(request, course_id):
+ user = request.user
+ if not is_moderator(user):
+ raise Http404('You are not allowed to view this page')
+ course = get_object_or_404(Course, creator=user, pk=course_id)
+ return my_render_to_response('yaksh/course_detail.html', {'course': course})
+
+
+@login_required
+def enroll(request, course_id, user_id, was_rejected=False):
+ user = request.user
+ if not is_moderator(user):
+ raise Http404('You are not allowed to view this page')
+ course = get_object_or_404(Course, creator=user, pk=course_id)
+ user = get_object_or_404(User, pk=user_id)
+ course.enroll(was_rejected, user)
+ return course_detail(request, course_id)
+
+
+@login_required
+def reject(request, course_id, user_id, was_enrolled=False):
+ user = request.user
+ if not is_moderator(user):
+ raise Http404('You are not allowed to view this page')
+ course = get_object_or_404(Course, creator=user, pk=course_id)
+ user = get_object_or_404(User, pk=user_id)
+ course.reject(was_enrolled, user)
+ return course_detail(request, course_id)
+
+
+@login_required
+def toggle_course_status(request, course_id):
+ user = request.user
+ if not is_moderator(user):
+ raise Http404('You are not allowed to view this page')
+ course = get_object_or_404(Course, creator=user, pk=course_id)
+ if course.active:
+ course.deactivate()
+ else:
+ course.activate()
+ course.save()
+ return course_detail(request, course_id)
+
+
@login_required
def show_statistics(request, questionpaper_id, attempt_number=None):
user = request.user
@@ -1201,7 +1300,7 @@ def monitor(request, questionpaper_id=None):
raise Http404('You are not allowed to view this page!')
if questionpaper_id is None:
- q_paper = QuestionPaper.objects.all()
+ q_paper = QuestionPaper.objects.filter(quiz__course__creator=user)
context = {'papers': [],
'quiz': None,
'quizzes': q_paper}
@@ -1209,10 +1308,12 @@ def monitor(request, questionpaper_id=None):
context_instance=ci)
# quiz_id is not None.
try:
- q_paper = QuestionPaper.objects.get(id=questionpaper_id)
+ q_paper = QuestionPaper.objects.get(id=questionpaper_id,
+ quiz__course__creator=user)
except QuestionPaper.DoesNotExist:
papers = []
q_paper = None
+ latest_attempts = []
else:
latest_attempts = []
papers = AnswerPaper.objects.filter(question_paper=q_paper).order_by(
@@ -1301,7 +1402,7 @@ def show_all_quiz(request):
forms = []
for j in data:
d = Quiz.objects.get(id=j)
- form = QuizForm()
+ form = QuizForm(user=user)
form.initial['start_date'] = d.start_date_time.date()
form.initial['start_time'] = d.start_date_time.time()
form.initial['end_date'] = d.end_date_time.date()
--
cgit
From b58a0b9831d8e6434362f776c89076c2d84e9b26 Mon Sep 17 00:00:00 2001
From: prathamesh
Date: Mon, 7 Mar 2016 15:29:36 +0530
Subject: Added tests for Course model
---
yaksh/models.py | 29 ++++++++--------
yaksh/tests.py | 105 +++++++++++++++++++++++++++++++++++++++++++++++---------
yaksh/views.py | 3 +-
3 files changed, 106 insertions(+), 31 deletions(-)
diff --git a/yaksh/models.py b/yaksh/models.py
index d6fe972..46fb9a3 100644
--- a/yaksh/models.py
+++ b/yaksh/models.py
@@ -62,6 +62,7 @@ def get_assignment_dir(instance, filename):
###############################################################################
class Course(models.Model):
+ """ Course for students"""
name = models.CharField(max_length=128)
enrollment = models.CharField(max_length=32, choices=enrollment_methods)
active = models.BooleanField(default=True)
@@ -77,17 +78,7 @@ class Course(models.Model):
def get_requests(self):
return self.requests.all()
- def reject(self, was_enrolled=False, *users):
- self.rejected.add(*users)
- if not was_enrolled:
- self.requests.remove(*users)
- else:
- self.students.remove(*users)
-
- def get_rejected(self):
- return self.rejected.all()
-
- def enroll(self, was_rejected=False, *users):
+ def enroll(self, was_rejected, *users):
self.students.add(*users)
if not was_rejected:
self.requests.remove(*users)
@@ -97,12 +88,25 @@ class Course(models.Model):
def get_enrolled(self):
return self.students.all()
+ def reject(self, was_enrolled, *users):
+ self.rejected.add(*users)
+ if not was_enrolled:
+ self.requests.remove(*users)
+ else:
+ self.students.remove(*users)
+
+ def get_rejected(self):
+ return self.rejected.all()
+
def is_enrolled(self, user_id):
return self.students.filter(id=user_id).exists()
def is_creator(self, user):
return self.creator == user
+ def is_self_enroll(self):
+ return True if self.enrollment == enrollment_methods[1][0] else False
+
def get_quizzes(self):
return self.quiz_set.all()
@@ -112,9 +116,6 @@ class Course(models.Model):
def deactivate(self):
self.active = False
- def is_self_enroll(self):
- return True if self.enrollment == 'open' else False
-
def __unicode__(self):
return self.name
diff --git a/yaksh/tests.py b/yaksh/tests.py
index 9c67c02..17e6130 100644
--- a/yaksh/tests.py
+++ b/yaksh/tests.py
@@ -1,8 +1,9 @@
from django.utils import unittest
from yaksh.models import User, Profile, Question, Quiz, QuestionPaper,\
- QuestionSet, AnswerPaper, Answer, TestCase
+ QuestionSet, AnswerPaper, Answer, TestCase, Course
import datetime, json
+
def setUpModule():
# create user profile
user = User.objects.create_user(username='demo_user',
@@ -13,6 +14,15 @@ def setUpModule():
email='demo@test.com')
Profile.objects.create(user=user, roll_number=1, institute='IIT',
department='Chemical', position='Student')
+ student = User.objects.create_user(username='demo_user3',
+ password='demo',
+ email='demo3@test.com')
+ Profile.objects.create(user=student, roll_number=3, institute='IIT',
+ department='Chemical', position='Student')
+
+ # create a course
+ course = Course.objects.create(name="Python Course",
+ enrollment="Enroll Request", creator=user)
# create 20 questions
for i in range(1, 21):
@@ -20,10 +30,11 @@ def setUpModule():
# create a quiz
Quiz.objects.create(start_date_time=datetime.datetime(2015, 10, 9, 10, 8, 15, 0),
- duration=30, active=False,
- attempts_allowed=-1, time_between_attempts=0,
- description='demo quiz', pass_criteria=40,
- language='Python', prerequisite=None)
+ duration=30, active=False,
+ attempts_allowed=-1, time_between_attempts=0,
+ description='demo quiz', pass_criteria=40,
+ language='Python', prerequisite=None,
+ course=course)
def tearDownModule():
@@ -62,14 +73,14 @@ class QuestionTestCases(unittest.TestCase):
func_name='def myfunc', kw_args='a=10,b=11',
pos_args='12,13', expected_answer='15')
answer_data = { "test": "",
- "user_answer": "demo_answer",
- "test_parameter": [{"func_name": "def myfunc",
- "expected_answer": "15",
- "test_id": self.testcase.id,
- "pos_args": ["12", "13"],
- "kw_args": {"a": "10",
+ "user_answer": "demo_answer",
+ "test_parameter": [{"func_name": "def myfunc",
+ "expected_answer": "15",
+ "test_id": self.testcase.id,
+ "pos_args": ["12", "13"],
+ "kw_args": {"a": "10",
"b": "11"}
- }],
+ }],
"id": self.question.id,
"ref_code_path": "",
}
@@ -93,10 +104,9 @@ class QuestionTestCases(unittest.TestCase):
def test_consolidate_answer_data(self):
""" Test consolidate_answer_data function """
- result = self.question.consolidate_answer_data([self.testcase],
+ result = self.question.consolidate_answer_data([self.testcase],
self.user_answer)
self.assertEqual(result, self.answer_data_json)
-
###############################################################################
@@ -107,7 +117,7 @@ class TestCaseTestCases(unittest.TestCase):
description='Write a function', points=1.0,
snippet='def myfunc()')
self.question.save()
- self.testcase = TestCase(question=self.question,
+ self.testcase = TestCase(question=self.question,
func_name='def myfunc', kw_args='a=10,b=11',
pos_args='12,13', expected_answer='15')
@@ -188,7 +198,7 @@ class QuestionPaperTestCases(unittest.TestCase):
def test_questionpaper(self):
""" Test question paper"""
self.assertEqual(self.question_paper.quiz.description, 'demo quiz')
- self.assertEqual(list(self.question_paper.fixed_questions.all()),
+ self.assertSequenceEqual(self.question_paper.fixed_questions.all(),
[self.questions[3], self.questions[5]])
self.assertTrue(self.question_paper.shuffle_questions)
@@ -350,3 +360,66 @@ class AnswerPaperTestCases(unittest.TestCase):
self.assertEqual(self.answerpaper.status, 'inprogress')
self.answerpaper.update_status('completed')
self.assertEqual(self.answerpaper.status, 'completed')
+
+
+###############################################################################
+class CourseTestCases(unittest.TestCase):
+ def setUp(self):
+ self.course = Course.objects.get(pk=1)
+ self.creator = User.objects.get(pk=1)
+ self.student1 = User.objects.get(pk=2)
+ self.student2 = User.objects.get(pk=3)
+ self.quiz = Quiz.objects.get(pk=1)
+
+ def test_is_creator(self):
+ """ Test is_creator method of Course"""
+ self.assertTrue(self.course.is_creator(self.creator))
+
+ def test_is_self_enroll(self):
+ """ Test is_self_enroll method of Course"""
+ self.assertFalse(self.course.is_self_enroll())
+
+ def test_deactivate(self):
+ """ Test deactivate method of Course"""
+ self.course.deactivate()
+ self.assertFalse(self.course.active)
+
+ def test_activate(self):
+ """ Test activate method of Course"""
+ self.course.activate()
+ self.assertTrue(self.course.active)
+
+ def test_request(self):
+ """ Test request and get_requests methods of Course"""
+ self.course.request(self.student1, self.student2)
+ self.assertSequenceEqual(self.course.get_requests(),
+ [self.student1, self.student2])
+
+ def test_enroll_reject(self):
+ """ Test enroll, reject, get_enrolled and get_rejected methods"""
+ self.assertSequenceEqual(self.course.get_enrolled(), [])
+ was_rejected = False
+ self.course.enroll(was_rejected, self.student1)
+ self.assertSequenceEqual(self.course.get_enrolled(), [self.student1])
+
+ self.assertSequenceEqual(self.course.get_rejected(), [])
+ was_enrolled = False
+ self.course.reject(was_enrolled, self.student2)
+ self.assertSequenceEqual(self.course.get_rejected(), [self.student2])
+
+ was_rejected = True
+ self.course.enroll(was_rejected, self.student2)
+ self.assertSequenceEqual(self.course.get_enrolled(),
+ [self.student1, self.student2])
+ self.assertSequenceEqual(self.course.get_rejected(), [])
+
+ was_enrolled = True
+ self.course.reject(was_enrolled, self.student2)
+ self.assertSequenceEqual(self.course.get_rejected(), [self.student2])
+ self.assertSequenceEqual(self.course.get_enrolled(), [self.student1])
+
+ self.assertTrue(self.course.is_enrolled(self.student1.id))
+
+ def test_get_quizzes(self):
+ """ Test get_quizzes method of Courses"""
+ self.assertSequenceEqual(self.course.get_quizzes(), [self.quiz])
diff --git a/yaksh/views.py b/yaksh/views.py
index 9540a06..ffe8d93 100644
--- a/yaksh/views.py
+++ b/yaksh/views.py
@@ -1206,7 +1206,8 @@ def self_enroll(request, course_id):
ci = RequestContext(request)
course = get_object_or_404(Course, pk=course_id)
if course.is_self_enroll():
- course.enroll(False, user)
+ was_rejected = False
+ course.enroll(was_rejected, user)
return my_redirect('/exam/manage/')
--
cgit
From e94f589eea5fbe85253d35f836d308bbfd339ff0 Mon Sep 17 00:00:00 2001
From: prathamesh
Date: Mon, 7 Mar 2016 16:29:47 +0530
Subject: Added a checkpoint, quizzes will be available only if the user is
enrolled for the respective course.
---
yaksh/models.py | 4 ++--
yaksh/tests.py | 2 +-
yaksh/views.py | 5 +++++
3 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/yaksh/models.py b/yaksh/models.py
index 46fb9a3..1bbd035 100644
--- a/yaksh/models.py
+++ b/yaksh/models.py
@@ -98,8 +98,8 @@ class Course(models.Model):
def get_rejected(self):
return self.rejected.all()
- def is_enrolled(self, user_id):
- return self.students.filter(id=user_id).exists()
+ def is_enrolled(self, user):
+ return user in self.students.all()
def is_creator(self, user):
return self.creator == user
diff --git a/yaksh/tests.py b/yaksh/tests.py
index 17e6130..848df74 100644
--- a/yaksh/tests.py
+++ b/yaksh/tests.py
@@ -418,7 +418,7 @@ class CourseTestCases(unittest.TestCase):
self.assertSequenceEqual(self.course.get_rejected(), [self.student2])
self.assertSequenceEqual(self.course.get_enrolled(), [self.student1])
- self.assertTrue(self.course.is_enrolled(self.student1.id))
+ self.assertTrue(self.course.is_enrolled(self.student1))
def test_get_quizzes(self):
""" Test get_quizzes method of Courses"""
diff --git a/yaksh/views.py b/yaksh/views.py
index ffe8d93..20a416d 100644
--- a/yaksh/views.py
+++ b/yaksh/views.py
@@ -184,6 +184,8 @@ def intro(request, questionpaper_id):
user = request.user
ci = RequestContext(request)
quest_paper = QuestionPaper.objects.get(id=questionpaper_id)
+ if not quest_paper.quiz.course.is_enrolled(user):
+ raise Http404('You are not allowed to view this page!')
attempt_number = quest_paper.quiz.attempts_allowed
time_lag = quest_paper.quiz.time_between_attempts
quiz_enable_time = quest_paper.quiz.start_date_time
@@ -822,6 +824,9 @@ def start(request, attempt_num=None, questionpaper_id=None):
'instructor/administrator. Please login again thereafter.'
return complete(request, msg, attempt_num, questionpaper_id)
+ if not questionpaper.quiz.course.is_enrolled(user):
+ raise Http404('You are not allowed to view this page!')
+
try:
old_paper = AnswerPaper.objects.get(
question_paper=questionpaper, user=user, attempt_number=attempt_num)
--
cgit
From c974da07d46709d3aa3640ba69c89d1a287ff3c1 Mon Sep 17 00:00:00 2001
From: prathamesh
Date: Mon, 7 Mar 2016 17:20:55 +0530
Subject: UI modification and checks for answerpaper before evaluating.
---
yaksh/templates/yaksh/course_detail.html | 4 ++--
yaksh/templates/yaksh/courses.html | 17 ++++++++++++++---
yaksh/views.py | 2 +-
3 files changed, 17 insertions(+), 6 deletions(-)
diff --git a/yaksh/templates/yaksh/course_detail.html b/yaksh/templates/yaksh/course_detail.html
index cae7335..ed56585 100644
--- a/yaksh/templates/yaksh/course_detail.html
+++ b/yaksh/templates/yaksh/course_detail.html
@@ -1,8 +1,8 @@
{% extends "manage.html" %}
-{% block title %} Course Detail {% endblock title %}
+{% block title %} Course {% endblock title %}
-{% block subtitle %} Course Detail for {{ course.name }} {% endblock %}
+{% block subtitle %} {{ course.name }} {% endblock %}
{% block css %}
diff --git a/yaksh/templates/yaksh/courses.html b/yaksh/templates/yaksh/courses.html
index 291a746..f8f8273 100644
--- a/yaksh/templates/yaksh/courses.html
+++ b/yaksh/templates/yaksh/courses.html
@@ -17,15 +17,26 @@
-
Course
+
+ Course
+ {% if course.active %}
+ Active
+ {% else %}
+ Closed
+ {% endif %}
+
- {% for quiz in course.get_quizzes %}
- {{ quiz.description }}
+ {% if course.get_quizzes %}
+ {% for quiz in course.get_quizzes %}
+ {{ quiz.description }}
{% endfor %}
+ {% else %}
+
No quiz
+ {% endif %}
diff --git a/yaksh/views.py b/yaksh/views.py
index 20a416d..9cd6fdb 100644
--- a/yaksh/views.py
+++ b/yaksh/views.py
@@ -949,7 +949,7 @@ def check(request, q_id, attempt_num=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, attempt_number=attempt_num,
+ paper = get_object_or_404(AnswerPaper, user=request.user, attempt_number=attempt_num,
question_paper=q_paper)
if q_id in paper.questions_answered:
--
cgit