diff options
-rw-r--r-- | yaksh/models.py | 19 | ||||
-rw-r--r-- | yaksh/templates/yaksh/grade_user.html | 4 | ||||
-rw-r--r-- | yaksh/templates/yaksh/monitor.html | 88 | ||||
-rw-r--r-- | yaksh/templatetags/custom_filters.py | 3 | ||||
-rw-r--r-- | yaksh/test_views.py | 3 | ||||
-rw-r--r-- | yaksh/views.py | 71 |
6 files changed, 103 insertions, 85 deletions
diff --git a/yaksh/models.py b/yaksh/models.py index bbb6900..662a8b4 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -1953,6 +1953,12 @@ class QuestionPaper(models.Model): list(self.random_questions.all()) return len(questions) > 0 + def get_questions_count(self): + que_count = self.fixed_questions.count() + for r_set in self.random_questions.all(): + que_count += r_set.num_questions + return que_count + def __str__(self): return "Question Paper for " + self.quiz.description @@ -2214,6 +2220,17 @@ class AnswerPaperManager(models.Manager): user.pop("id") user["total_marks"] = user_marks + def get_questions_attempted(self, answerpaper_ids): + answers = Answer.objects.filter( + answerpaper__id__in=answerpaper_ids + ).values("question_id", "answerpaper__id") + df = pd.DataFrame(answers) + answerpapers = df.groupby("answerpaper__id") + question_attempted = {} + for ap in answerpapers: + question_attempted[ap[0]] = len(ap[1]["question_id"].unique()) + return question_attempted + ############################################################################### class AnswerPaper(models.Model): @@ -2472,7 +2489,7 @@ class AnswerPaper(models.Model): """ q_a = {} for question in self.questions.all(): - answers = question.answer_set.filter(answerpaper=self) + answers = question.answer_set.filter(answerpaper=self).distinct() if not answers.exists(): q_a[question] = [None, 0.0] continue diff --git a/yaksh/templates/yaksh/grade_user.html b/yaksh/templates/yaksh/grade_user.html index 86b7c47..4e1db2b 100644 --- a/yaksh/templates/yaksh/grade_user.html +++ b/yaksh/templates/yaksh/grade_user.html @@ -2,9 +2,9 @@ {% load custom_filters %} {% load static %} -{% block title %} Grader {% endblock %} +{% block title %} Quizzes {% endblock %} -{% block pagetitle %} Grader {% endblock pagetitle %} +{% block pagetitle %} Quizzes {% endblock pagetitle %} {% block script %} <script type="text/javascript" src="{% static 'yaksh/js/jquery.tablesorter.min.js' %}"> diff --git a/yaksh/templates/yaksh/monitor.html b/yaksh/templates/yaksh/monitor.html index 5e8fdc3..ca5a7fc 100644 --- a/yaksh/templates/yaksh/monitor.html +++ b/yaksh/templates/yaksh/monitor.html @@ -39,9 +39,20 @@ $(document).ready(function() {% block content %} <div class="container-fluid"> + {% if messages %} + {% for message in messages %} + <div class="alert alert-dismissible alert-{{ message.tags }}"> + <button type="button" class="close" data-dismiss="alert"> + <i class="fa fa-close"></i> + </button> + <strong>{{ message }}</strong> + </div> + {% endfor %} + {% endif %} {% if quiz %} {% if papers %} - <div class="card"> + <div class="row"> + <div class="card col"> <div class="table-responsive"> <table id="course-detail" class="table"> <tr> @@ -52,40 +63,32 @@ $(document).ready(function() <td><b>Quiz Name: </b></td> <td>{{quiz.description}}</td> </tr> - <tr> - <td><b>Number of papers:  </b></td> - <td>{{papers|length}}</td> - </tr> - <tr> - <td><b>Papers Completed:  </b></td> - <td> - {% completed papers as completed_papers %} - <b>{{completed_papers}}</b> - </td> - </tr> - <tr> - <td><b>Papers in progress:  </b></td> - <td> - {% inprogress papers as inprogress_papers %} - <b>{{ inprogress_papers }}</b> - </td> - </tr> </table> </div> </div> - <br> - <br> - {% if messages %} - {% for message in messages %} - <div class="alert alert-dismissible alert-{{ message.tags }}"> - <button type="button" class="close" data-dismiss="alert"> - <i class="fa fa-close"></i> - </button> - <strong>{{ message }}</strong> - </div> - {% endfor %} - {% endif %} - <br> + <div class="card col"> + <div class="table-responsive"> + <table id="course-detail" class="table"> + <tr> + <td><b>Number of papers:  </b></td> + <td>{{total_papers}}</td> + </tr> + <tr> + <td><b>Papers Completed:  </b></td> + <td> + <b>{{completed_papers}}</b> + </td> + </tr> + <tr> + <td><b>Papers in progress:  </b></td> + <td> + <b>{{ inprogress_papers }}</b> + </td> + </tr> + </table> + </div> + </div> + </div> <div class="row"> <div class="col-md-4"> <button type="button" class="btn btn-info" data-toggle="modal" data-target="#csvModal"> @@ -133,7 +136,7 @@ $(document).ready(function() </div> <br> <div class="card"> - {% if latest_attempts|length > 10 %} + {% if total_papers > 10 %} <div class="table-responsive" style="height: 800px"> {% else %} <div class="table-responsive"> @@ -145,7 +148,7 @@ $(document).ready(function() <th> Name <i class="fa fa-sort"></i> </th> <th> Roll No <i class="fa fa-sort"></i> </th> <th> Marks <i class="fa fa-sort"></i> </th> - <th> Attempts <i class="fa fa-sort"></i> </th> + <th> Questions Attempted <i class="fa fa-sort"></i> </th> <th> Time Left <i class="fa fa-sort"></i> </th> <th> Status <i class="fa fa-sort"></i> </th> <th> Extend time <i class="fa fa-sort"></i> </th> @@ -153,14 +156,19 @@ $(document).ready(function() </tr> </thead> <tbody class="list"> - {% for paper in latest_attempts %} + {% for paper in papers %} <tr> <td>{{forloop.counter}}</td> - <td> <a href="{% url 'yaksh:user_data' paper.user.id paper.question_paper.id course.id %}"> - {{ paper.user.get_full_name.title }}</a> </td> - <td> {{ paper.user.profile.roll_number }} </td> + {% with paper.user as student %} + <td> <a href="{% url 'yaksh:user_data' paper.user_id paper.question_paper_id course.id %}"> + {{ student.get_full_name.title }}</a> </td> + <td> {{ student.profile.roll_number }} </td> + {% endwith %} <td> {{ paper.marks_obtained }} </td> - <td> {{ paper.answers.count }} </td> + <td> + {% get_dict_value questions_attempted paper.id as que_attempt %} + {{que_attempt}} out of {{questions_count}} + </td> <td id="time_left{{forloop.counter0}}"> {{ paper.time_left }} </td> <td> {% if paper.is_attempt_inprogress %} <span class="badge badge-warning"> Inprogress </span> @@ -229,7 +237,7 @@ $(document).ready(function() <div class="col-md-12"> <div class="alert alert-warning"> <center> - <h4>No Users Found for {{ quiz.description }}</h4> + <p>No Users Found for {{ quiz.description }}</p> </center> </div> </div> diff --git a/yaksh/templatetags/custom_filters.py b/yaksh/templatetags/custom_filters.py index 201ec50..b026159 100644 --- a/yaksh/templatetags/custom_filters.py +++ b/yaksh/templatetags/custom_filters.py @@ -218,3 +218,6 @@ def get_percent_value(dictionary, key, total): return round((dictionary.get(str(key), 0)/total)*100) +@register.simple_tag +def get_dict_value(dictionary, key): + return dictionary.get(key, 0) diff --git a/yaksh/test_views.py b/yaksh/test_views.py index 8973d9f..58b7506 100644 --- a/yaksh/test_views.py +++ b/yaksh/test_views.py @@ -614,10 +614,7 @@ class TestMonitor(TestCase): self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, "yaksh/monitor.html") - self.assertEqual(response.context['msg'], "Quiz Results") self.assertEqual(response.context['papers'][0], self.answerpaper) - self.assertEqual(response.context['latest_attempts'][0], - self.answerpaper) def test_get_quiz_user_data(self): """ diff --git a/yaksh/views.py b/yaksh/views.py index 731d781..2b5ea8d 100644 --- a/yaksh/views.py +++ b/yaksh/views.py @@ -1363,49 +1363,42 @@ def monitor(request, quiz_id=None, course_id=None): if not is_moderator(user): raise Http404('You are not allowed to view this page!') - # quiz_id is not None. - try: - quiz = get_object_or_404(Quiz, id=quiz_id) - course = get_object_or_404(Course, id=course_id) - if not course.is_creator(user) and not course.is_teacher(user): - raise Http404('This course does not belong to you') - q_paper = QuestionPaper.objects.filter(quiz__is_trial=False, - quiz_id=quiz_id).distinct() - except (QuestionPaper.DoesNotExist, Course.DoesNotExist): - papers = [] - q_paper = None - latest_attempts = [] - attempt_numbers = [] + course = get_object_or_404(Course, id=course_id) + if not course.is_creator(user) and not course.is_teacher(user): + raise Http404('This course does not belong to you') + + quiz = get_object_or_404(Quiz, id=quiz_id) + q_paper = QuestionPaper.objects.filter(quiz__is_trial=False, + quiz_id=quiz_id).distinct().last() + attempt_numbers = AnswerPaper.objects.get_attempt_numbers( + q_paper.id, course.id + ) + latest_attempt_num = max(list(attempt_numbers)) if attempt_numbers else 0 + questions_count = 0 + questions_attempted = {} + completed_papers = 0 + inprogress_papers = 0 + papers = AnswerPaper.objects.filter( + question_paper_id=q_paper.id, + course_id=course_id, attempt_number=latest_attempt_num + ).order_by('user__first_name') + if not papers.exists(): + messages.warning(request, "No AnswerPapers found") else: - if q_paper: - attempt_numbers = AnswerPaper.objects.get_attempt_numbers( - q_paper.last().id, course.id) - else: - attempt_numbers = [] - latest_attempts = [] - papers = AnswerPaper.objects.filter( - question_paper_id=q_paper.first().id, - course_id=course_id).order_by( - 'user__profile__roll_number' + questions_count = q_paper.get_questions_count() + questions_attempted = AnswerPaper.objects.get_questions_attempted( + papers.values_list("id", flat=True) ) - users = papers.values_list('user').distinct() - for auser in users: - last_attempt = papers.filter(user__in=auser).aggregate( - last_attempt_num=Max('attempt_number') - ) - latest_attempts.append( - papers.get( - user__in=auser, - attempt_number=last_attempt['last_attempt_num'] - ) - ) + completed_papers = papers.filter(status="completed").count() + inprogress_papers = papers.filter(status="inprogress").count() context = { - "papers": papers, - "quiz": quiz, - "msg": "Quiz Results", - "latest_attempts": latest_attempts, + "papers": papers, "quiz": quiz, + "inprogress_papers": inprogress_papers, "attempt_numbers": attempt_numbers, - "course": course + "course": course, "total_papers": papers.count(), + "completed_papers": completed_papers, + "questions_attempted": questions_attempted, + "questions_count": questions_count } return my_render_to_response(request, 'yaksh/monitor.html', context) |