From e3d289ca93047a1632a74ecfd5bc996433f3edb4 Mon Sep 17 00:00:00 2001 From: adityacp Date: Tue, 4 Apr 2017 16:16:56 +0530 Subject: Change in views and urls - Change monitor and grade_user function in views - Change url to get quiz id instead of question paper id --- yaksh/urls.py | 2 +- yaksh/views.py | 43 +++++++++++++++++++++++++------------------ 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/yaksh/urls.py b/yaksh/urls.py index ad58985..9108b7b 100644 --- a/yaksh/urls.py +++ b/yaksh/urls.py @@ -40,7 +40,7 @@ urlpatterns = [ url(r'^manage/showquestionpapers/$', views.show_all_questionpapers), url(r'^manage/showquestionpapers/(?P\d+)/$',\ views.show_all_questionpapers), - url(r'^manage/monitor/(?P\d+)/$', views.monitor), + url(r'^manage/monitor/(?P\d+)/$', views.monitor), url(r'^manage/user_data/(?P\d+)/(?P\d+)/$', views.user_data), url(r'^manage/user_data/(?P\d+)/$', views.user_data), diff --git a/yaksh/views.py b/yaksh/views.py index 2adc2c3..c5aeb1c 100644 --- a/yaksh/views.py +++ b/yaksh/views.py @@ -284,9 +284,11 @@ def prof_manage(request, msg=None): user = request.user ci = RequestContext(request) if user.is_authenticated() and is_moderator(user): - question_papers = QuestionPaper.objects.filter(quiz__course__creator=user, - quiz__is_trial=False - ) + question_papers = QuestionPaper.objects.filter( + Q(quiz__course__creator=user) | + Q(quiz__course__teachers=user), + quiz__is_trial=False + ) trial_paper = AnswerPaper.objects.filter(user=user, question_paper__quiz__is_trial=True ) @@ -306,9 +308,9 @@ def prof_manage(request, msg=None): for paper in question_papers: answer_papers = AnswerPaper.objects.filter(question_paper=paper) users_passed = AnswerPaper.objects.filter(question_paper=paper, - passed=True).count() + passed=True).distinct().count() users_failed = AnswerPaper.objects.filter(question_paper=paper, - passed=False).count() + passed=False).distinct().count() temp = paper, answer_papers, users_passed, users_failed users_per_paper.append(temp) context = {'user': user, 'users_per_paper': users_per_paper, @@ -759,7 +761,7 @@ def show_statistics(request, questionpaper_id, attempt_number=None): @login_required -def monitor(request, questionpaper_id=None): +def monitor(request, quiz_id=None): """Monitor the progress of the papers taken so far.""" user = request.user @@ -767,14 +769,12 @@ def monitor(request, questionpaper_id=None): if not user.is_authenticated() or not is_moderator(user): raise Http404('You are not allowed to view this page!') - if questionpaper_id is None: - q_paper = QuestionPaper.objects.filter(Q(quiz__course__creator=user) | - Q(quiz__course__teachers=user), - quiz__is_trial=False - ).distinct() - context = {'papers': [], - 'quiz': None, - 'quizzes': q_paper} + if quiz_id is None: + course_details = Course.objects.filter(Q(creator=user) | + Q(teachers=user), + is_trial=False).distinct() + context = {'papers': [], "course_details": course_details, + "msg": "Monitor"} return my_render_to_response('yaksh/monitor.html', context, context_instance=ci) # quiz_id is not None. @@ -782,7 +782,10 @@ def monitor(request, questionpaper_id=None): q_paper = QuestionPaper.objects.filter(Q(quiz__course__creator=user) | Q(quiz__course__teachers=user), quiz__is_trial=False, - id=questionpaper_id).distinct() + quiz_id=quiz_id).distinct() + quiz = get_object_or_404(Quiz, id=quiz_id) + if not quiz.course.is_creator(user) and not quiz.course.is_teacher(user): + raise Http404('This course does not belong to you') except QuestionPaper.DoesNotExist: papers = [] q_paper = None @@ -797,8 +800,8 @@ def monitor(request, questionpaper_id=None): last_attempt_num=Max('attempt_number')) latest_attempts.append(papers.get(user__in=auser, attempt_number=last_attempt['last_attempt_num'])) - context = {'papers': papers, 'quiz': q_paper, 'quizzes': None, - 'latest_attempts': latest_attempts,} + context = {'papers': papers, "quiz": quiz, "msg": "Quiz Results", + 'latest_attempts': latest_attempts} return my_render_to_response('yaksh/monitor.html', context, context_instance=ci) @@ -1082,7 +1085,11 @@ def grade_user(request, quiz_id=None, user_id=None, attempt_number=None): .values("id") user_details = AnswerPaper.objects\ .get_users_for_questionpaper(questionpaper_id) - context = {"users": user_details, "quiz_id": quiz_id} + quiz = get_object_or_404(Quiz, id=quiz_id) + if not quiz.course.is_creator(current_user) and not \ + quiz.course.is_teacher(current_user): + raise Http404('This course does not belong to you') + context = {"users": user_details, "quiz_id": quiz_id, "quiz": quiz} if user_id is not None: attempts = AnswerPaper.objects.get_user_all_attempts\ -- cgit From 9b8b99b69066f6a627a2a660d6ad2e63e31f446a Mon Sep 17 00:00:00 2001 From: adityacp Date: Tue, 4 Apr 2017 16:24:52 +0530 Subject: Change in templates - Display course name and quiz name in Grade user page and monitor page - Give html title to all templates - Display alloted course's quizzes in moderator dashboard --- yaksh/templates/yaksh/course_detail.html | 4 +- yaksh/templates/yaksh/courses.html | 2 +- yaksh/templates/yaksh/grade_user.html | 18 ++++--- yaksh/templates/yaksh/moderator_dashboard.html | 4 ++ yaksh/templates/yaksh/monitor.html | 67 +++++++++++++++----------- yaksh/templates/yaksh/showquestions.html | 1 + 6 files changed, 59 insertions(+), 37 deletions(-) diff --git a/yaksh/templates/yaksh/course_detail.html b/yaksh/templates/yaksh/course_detail.html index 4b7efaf..81569fa 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 {% endblock title %} +{% block title %} Course Details {% endblock title %} -{% block subtitle %} {{ course.name }} {% endblock %} +{% block pagetitle %} Course Details for {{ course.name|title }} {% endblock %} {% block script %} diff --git a/yaksh/templates/yaksh/courses.html b/yaksh/templates/yaksh/courses.html index 970d488..766b444 100644 --- a/yaksh/templates/yaksh/courses.html +++ b/yaksh/templates/yaksh/courses.html @@ -1,5 +1,5 @@ {% extends "manage.html" %} - +{% block title %} Courses {% endblock %} {% block pagetitle %} Courses {% endblock pagetitle %} {% block content %} {% if not courses %} diff --git a/yaksh/templates/yaksh/grade_user.html b/yaksh/templates/yaksh/grade_user.html index 1cb1f99..67f25a4 100644 --- a/yaksh/templates/yaksh/grade_user.html +++ b/yaksh/templates/yaksh/grade_user.html @@ -1,5 +1,7 @@ {% extends "manage.html" %} +{% block title %} Grade User {% endblock %} + {% block pagetitle %} Grade User {% endblock pagetitle %} {% block content %} @@ -8,11 +10,10 @@ {% endblock script %} - {% if course_details %} - + @@ -37,23 +38,25 @@ {% endif %}
-{%if users %} +{% if not course_details %} +{% if users %}
{% for user in users %}

{{user.user__first_name}} {{user.user__last_name}}

{% endfor %}
+{% else %} +

No Users Found for {{ quiz.description }}

+{% endif %} {% endif %} - -
{% if data %}

Showing paper for {{data.user.get_full_name.title}}

-

Name:{{ data.user.get_full_name.title }} +

Name: {{ data.user.get_full_name.title }} {% if data.profile %}

Roll number: {{ data.profile.roll_number }} @@ -68,7 +71,8 @@


{{ paper.total_marks }} -

Quiz: {{ paper.question_paper.quiz.description }}

+

Course: {{ paper.question_paper.quiz.course.name }}

+

Quiz: {{ paper.question_paper.quiz.description }}

Attempt Number: {{paper.attempt_number}} diff --git a/yaksh/templates/yaksh/moderator_dashboard.html b/yaksh/templates/yaksh/moderator_dashboard.html index 0468ed9..faccffe 100644 --- a/yaksh/templates/yaksh/moderator_dashboard.html +++ b/yaksh/templates/yaksh/moderator_dashboard.html @@ -9,12 +9,16 @@

List of quizzes! Click on the given links to have a look at answer papers for a quiz.

CoursesCourses Quizzes
+ {% for paper, answer_papers, users_passed, users_failed in users_per_paper %} + diff --git a/yaksh/templates/yaksh/monitor.html b/yaksh/templates/yaksh/monitor.html index d2c89ce..9ce0dc4 100644 --- a/yaksh/templates/yaksh/monitor.html +++ b/yaksh/templates/yaksh/monitor.html @@ -1,15 +1,16 @@ {% extends "manage.html" %} {% load custom_filters %} - -{% block pagetitle %} Quiz results {% endblock pagetitle %} +{% block title %} Monitor {% endblock %} +{% block pagetitle %} {{ msg }} {% endblock pagetitle %} {% block meta %} {% endblock meta %} {% block script %} +{% if papers %} - +{% endif %} {% endblock %} - -{% block subtitle %} - {% if not quizzes and not quiz %} - Quiz Results - {% endif %} - {% if quizzes %} - Available Quizzes - {% endif %} - {% if quiz %} - {{ quiz.description }} Results - {% endif %} -{% endblock %} {% block content %} - {% if not quizzes and not quiz %} -
No quizzes available.
- {% endif %} {# ############################################################### #} {# This is rendered when we are just viewing exam/monitor #} -{% if quizzes %} - + +{% if course_details %} +
Course Quiz Taken By No. of users Passed No. of users Failed
+ {{ paper.quiz.course.name }} + {{ paper.quiz.description }}
+ + + + + + {% for course in course_details %} + + + + {% if course.get_quizzes %} + + {% else %} + + {% endif %} + + {% endfor %} +
Courses Quizzes
    {{course.name}}
+ {% for quiz in course.get_quizzes %} +
  • + {{quiz.description}} +
  • + {% endfor %} +
    No quiz
    {% endif %} {# ############################################################### #} {# This is rendered when we are just viewing exam/monitor/quiz_num #} +{% if msg != "Monitor" %} {% if quiz %} - {% if papers %} +

    Course Name: {{ quiz.course.name }}

    +

    Quiz Name: {{ quiz.description }}

    Number of papers: {{ papers|length }}

    {% completed papers as completed_papers %} {# template tag used to get the count of completed papers #} @@ -80,6 +88,7 @@ $(document).ready(function() Marks obtained Attempts Time Remaining + Status @@ -93,13 +102,17 @@ $(document).ready(function() {{ paper.marks_obtained }} {{ paper.answers.count }} {{ paper.time_left }} + {{ paper.status }} {% endfor %} {% else %} -

    No answer papers so far.

    +

    No answer papers found for {{ quiz.description }}

    {% endif %} {# if papers #} +{% else %} +

    No Quiz Found

    +{% endif %} {% endif %} {% endblock %} diff --git a/yaksh/templates/yaksh/showquestions.html b/yaksh/templates/yaksh/showquestions.html index 157b378..a136ddf 100644 --- a/yaksh/templates/yaksh/showquestions.html +++ b/yaksh/templates/yaksh/showquestions.html @@ -1,5 +1,6 @@ {% extends "manage.html" %} +{% block title %} Questions {% endblock %} {% block pagetitle %} List of Questions {% endblock pagetitle %} -- cgit From 592353ba30178654975f4c64602414cac7f41a9d Mon Sep 17 00:00:00 2001 From: adityacp Date: Fri, 31 Mar 2017 16:33:51 +0530 Subject: Add download assignment feature for assignment based questions - Add method in AssignmentUpload to get assignments - Add function in views to serve assignment files --- yaksh/models.py | 24 ++++++++++++++++- yaksh/views.py | 83 ++++++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 91 insertions(+), 16 deletions(-) diff --git a/yaksh/models.py b/yaksh/models.py index 802a1fc..2d3aadb 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -79,7 +79,8 @@ test_status = ( def get_assignment_dir(instance, filename): return os.sep.join(( - instance.user.username, str(instance.assignmentQuestion.id), filename + instance.question_paper.quiz.description, instance.user.username, + str(instance.assignmentQuestion.id), filename )) @@ -1310,7 +1311,26 @@ class AssignmentUpload(models.Model): user = models.ForeignKey(User) assignmentQuestion = models.ForeignKey(Question) assignmentFile = models.FileField(upload_to=get_assignment_dir) + question_paper = models.ForeignKey(QuestionPaper, blank=True, null=True) + def get_assignments(self, qp_id, que_id=None, user_id=None): + if que_id and user_id: + assignment_files = AssignmentUpload.objects.filter( + assignmentQuestion_id=que_id, user_id=user_id, + question_paper_id=qp_id + ) + user_name = User.objects.get(id=user_id) + file_name = user_name.get_full_name().replace(" ", "_") + else: + assignment_files = AssignmentUpload.objects.filter( + question_paper_id=qp_id + ) + + file_name = "%s_Assignment_files" %( + assignment_files[0].question_paper.quiz.description + ) + + return assignment_files, file_name ############################################################################### class TestCase(models.Model): @@ -1372,7 +1392,9 @@ class HookTestCase(TestCase): mark_fraction - Float, indicating fraction of the weight to a test case error - String, error message if success is false + In case of assignment upload there will be no user answer ''' + success = False err = "Incorrect Answer" # Please make this more specific mark_fraction = 0.0 diff --git a/yaksh/views.py b/yaksh/views.py index db7498c..d0735bd 100644 --- a/yaksh/views.py +++ b/yaksh/views.py @@ -22,6 +22,11 @@ from taggit.models import Tag from itertools import chain import json import six +import zipfile +try: + from StringIO import StringIO as string_io +except ImportError: + from io import BytesIO as string_io # Local imports. from yaksh.models import get_model_class, Quiz, Question, QuestionPaper, QuestionSet, Course from yaksh.models import Profile, Answer, AnswerPaper, User, TestCase, FileUpload,\ @@ -494,20 +499,28 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None): # validation if 'assignment' in request.FILES: assignment_filename = request.FILES.getlist('assignment') + qp = QuestionPaper.objects.get(id=questionpaper_id) for fname in assignment_filename: if AssignmentUpload.objects.filter( assignmentQuestion=current_question, - assignmentFile__icontains=fname, user=user).exists(): + assignmentFile__icontains=fname, user=user, + question_paper=questionpaper_id).exists(): assign_file = AssignmentUpload.objects.get( assignmentQuestion=current_question, - assignmentFile__icontains=fname, user=user) + assignmentFile__icontains=fname, user=user, + question_paper=questionpaper_id) os.remove(assign_file.assignmentFile.path) assign_file.delete() AssignmentUpload.objects.create(user=user, - assignmentQuestion=current_question, assignmentFile=fname + assignmentQuestion=current_question, assignmentFile=fname, + question_paper=qp ) user_answer = 'ASSIGNMENT UPLOADED' if not current_question.grade_assignment_upload: + new_answer = Answer(question=current_question, answer=user_answer, + correct=False, error=json.dumps([])) + new_answer.save() + paper.answers.add(new_answer) next_q = paper.add_completed_question(current_question.id) return show_question(request, next_q, paper) else: @@ -910,14 +923,15 @@ def design_questionpaper(request, quiz_id, questionpaper_id=None): if 'remove-fixed' in request.POST: question_ids = request.POST.getlist('added-questions', None) - que_order = question_paper.fixed_question_order.split(",") - for qid in question_ids: - que_order.remove(qid) - if que_order: - question_paper.fixed_question_order = ",".join(que_order) - else: - question_paper.fixed_question_order = "" - question_paper.save() + if question_paper.fixed_question_order: + que_order = question_paper.fixed_question_order.split(",") + for qid in question_ids: + que_order.remove(qid) + if que_order: + question_paper.fixed_question_order = ",".join(que_order) + else: + question_paper.fixed_question_order = "" + question_paper.save() question_paper.fixed_questions.remove(*question_ids) if 'add-random' in request.POST: @@ -1099,7 +1113,12 @@ def grade_user(request, quiz_id=None, user_id=None, attempt_number=None): .values("id") user_details = AnswerPaper.objects\ .get_users_for_questionpaper(questionpaper_id) - context = {"users": user_details, "quiz_id": quiz_id} + quiz_assignment_file_status = AssignmentUpload.objects.filter( + question_paper_id=questionpaper_id + ).exists() + context = {"users": user_details, "quiz_id": quiz_id, + "quiz_file_status": quiz_assignment_file_status + } if user_id is not None: attempts = AnswerPaper.objects.get_user_all_attempts\ @@ -1109,14 +1128,18 @@ def grade_user(request, quiz_id=None, user_id=None, attempt_number=None): attempt_number = attempts[0].attempt_number except IndexError: raise Http404('No attempts for paper') - + user_assignment_file_status = AssignmentUpload.objects.filter( + question_paper_id=questionpaper_id, + user_id=user_id + ).exists() user = User.objects.get(id=user_id) data = AnswerPaper.objects.get_user_data(user, questionpaper_id, attempt_number ) - context = {'data': data, "quiz_id": quiz_id, "users": user_details, - "attempts": attempts, "user_id": user_id + "attempts": attempts, "user_id": user_id, + "user_file_status": user_assignment_file_status, + "quiz_file_status": quiz_assignment_file_status } if request.method == "POST": papers = data['papers'] @@ -1403,3 +1426,33 @@ def download_course_csv(request, course_id): for student in students: writer.writerow(student) return response + + +@login_required +def download_assignment_file(request, questionpaper_id, question_id=None, + user_id=None): + user = request.user + if not is_moderator(user): + raise Http404('You are not allowed to view this page!') + assignment = AssignmentUpload() + assignment_files, file_name = assignment.get_assignments(questionpaper_id, + question_id, user_id + ) + zipfile_name = string_io() + zip_file = zipfile.ZipFile(zipfile_name, "w") + for f_name in assignment_files: + name = f_name.user.get_full_name().replace(" ", "_") + folder_name = os.sep.join((name, os.path.basename( + f_name.assignmentFile.name)) + ) + zip_file.write(f_name.assignmentFile.path, folder_name + ) + zip_file.close() + zipfile_name.seek(0) + response = HttpResponse(content_type='application/zip') + response['Content-Disposition'] = '''attachment;\ + filename={0}'''.format( + file_name.replace(" ", "_") + ) + response.write(zipfile_name.read()) + return response -- cgit From bd8c2c653a06e29dcf7a1a0103f7735f46f0c488 Mon Sep 17 00:00:00 2001 From: adityacp Date: Fri, 31 Mar 2017 16:37:07 +0530 Subject: Change in templates and js and urls - Add urls to download quiz assignments in urls.p - Catch Http404 exception message in 404.html template - Add download assignment links for quiz in grade_user.html - Fix javascript validation in add_question.js --- yaksh/static/yaksh/js/add_question.js | 3 +- yaksh/templates/404.html | 2 +- yaksh/templates/yaksh/grade_user.html | 60 +++++++++++++++++++++-------------- yaksh/urls.py | 4 +++ 4 files changed, 42 insertions(+), 27 deletions(-) diff --git a/yaksh/static/yaksh/js/add_question.js b/yaksh/static/yaksh/js/add_question.js index 05752b4..5bec8c6 100644 --- a/yaksh/static/yaksh/js/add_question.js +++ b/yaksh/static/yaksh/js/add_question.js @@ -122,9 +122,8 @@ function textareaformat() }); document.getElementById('my').innerHTML = document.getElementById('id_description').value ; - if (document.getElementById('id_grade_assignment_upload').checked || - document.getElementById('id_type').val() == 'upload'){ + document.getElementById('id_type').value == 'upload'){ $("#id_grade_assignment_upload").prop("disabled", false); } else{ diff --git a/yaksh/templates/404.html b/yaksh/templates/404.html index 7d33dd3..8d43ec5 100644 --- a/yaksh/templates/404.html +++ b/yaksh/templates/404.html @@ -1,5 +1,5 @@ {% extends "base.html" %} {% block content %} -The requested page does not exist. +{{ exception }} {% endblock %} diff --git a/yaksh/templates/yaksh/grade_user.html b/yaksh/templates/yaksh/grade_user.html index 1cb1f99..69c03c9 100644 --- a/yaksh/templates/yaksh/grade_user.html +++ b/yaksh/templates/yaksh/grade_user.html @@ -46,7 +46,11 @@ {% endif %} +{% if quiz_file_status %} + + Download All Assignments +{% endif %}
    {% if data %} @@ -69,7 +73,6 @@ {{ paper.total_marks }}

    Quiz: {{ paper.question_paper.quiz.description }}

    -

    Attempt Number: {{paper.attempt_number}} -
    Questions correctly answered: {{ paper.get_answered_str }}
    Total attempts at questions: {{ paper.answers.count }}
    Marks obtained: {{ paper.marks_obtained }}
    @@ -95,7 +97,6 @@ Status : Failed
    Status : Passed
    {% endif %}

    - {% if paper.answers.count %}

    Report


    @@ -122,8 +123,8 @@ Status : Passed
    {% endif %} method="post"> {% csrf_token %} -{% for question, answers in paper.get_question_answers.items %} +{% for question, answers in paper.get_question_answers.items %}
    Details: {{forloop.counter}}. {{ question.summary }} @@ -153,7 +154,6 @@ Status : Passed
    {{ testcase.error_margin|safe }} {% endif %} {% endfor %} - {% else %}
    Test cases:
    {% for testcase in question.get_test_cases %} @@ -163,29 +163,41 @@ Status : Passed
    Student answer:
    - {% for ans in answers %} - {% if ans.answer.correct %} -
    -
    Correct answer: + {% if question.type == "upload" %} + {% if user_file_status %} + +
    + Assignment File for {{ data.user.get_full_name.title }} +
    +
    + {% else %} +
    No Assignment submitted by {{ data.user.get_full_name.title }}
    + {% endif %} + {% else %} + {% for ans in answers %} + {% if ans.answer.correct %} +
    +
    Correct answer: + {% else %} +
    +
    Error: + {% endif %} + {% for err in ans.error_list %} +
    {{ err }}
    + {% endfor %} +
    +
    + {% if question.type != "code" %} +
    + {{ ans.answer.answer.strip|safe }} +
    {% else %} -
    -
    Error: +
    {{ ans.answer.answer.strip|safe }}
    {% endif %} - {% for err in ans.error_list %} -
    {{ err }}
    +
    +
    {% endfor %} -
    -
    - {% if question.type != "code" %} -
    - {{ ans.answer.answer.strip|safe }} -
    - {% else %} -
    {{ ans.answer.answer.strip|safe }}
    {% endif %} -
    -
    - {% endfor %} {% with answers|last as answer %} Marks: \d+)/$', views.download_course_csv), + url(r'^manage/download/user_assignment/(?P\d+)/(?P\d+)/(?P\d+)/$', + views.download_assignment_file), + url(r'^manage/download/quiz_assignments/(?P\d+)/$', + views.download_assignment_file) ] -- cgit From 32911e9a094e7f91ca132f98927d110049c99401 Mon Sep 17 00:00:00 2001 From: adityacp Date: Fri, 31 Mar 2017 16:40:35 +0530 Subject: Add new migrations for assignment upload --- yaksh/migrations/0005_auto_20170410_1024.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 yaksh/migrations/0005_auto_20170410_1024.py diff --git a/yaksh/migrations/0005_auto_20170410_1024.py b/yaksh/migrations/0005_auto_20170410_1024.py new file mode 100644 index 0000000..13b4cce --- /dev/null +++ b/yaksh/migrations/0005_auto_20170410_1024.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.5 on 2017-04-10 10:24 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('yaksh', '0004_auto_20170331_0632'), + ] + + operations = [ + migrations.AddField( + model_name='assignmentupload', + name='question_paper', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='yaksh.QuestionPaper'), + ), + migrations.AlterField( + model_name='hooktestcase', + name='hook_code', + field=models.TextField(default='def check_answer(user_answer):\n \'\'\' Evaluates user answer to return -\n success - Boolean, indicating if code was executed correctly\n mark_fraction - Float, indicating fraction of the\n weight to a test case\n error - String, error message if success is false\n\n In case of assignment upload there will be no user answer \'\'\'\n\n success = False\n err = "Incorrect Answer" # Please make this more specific\n mark_fraction = 0.0\n\n # write your code here\n\n return success, err, mark_fraction\n\n'), + ), + ] -- cgit From 5623c1225f66831d5e5db2089218b7904c3124b6 Mon Sep 17 00:00:00 2001 From: adityacp Date: Mon, 10 Apr 2017 16:15:59 +0530 Subject: Change download assignemnts to get files using quiz --- yaksh/models.py | 8 ++++---- yaksh/templates/yaksh/grade_user.html | 2 +- yaksh/urls.py | 4 ++-- yaksh/views.py | 25 +++++++++++++------------ 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/yaksh/models.py b/yaksh/models.py index 2d3aadb..5ec3062 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -1313,17 +1313,17 @@ class AssignmentUpload(models.Model): assignmentFile = models.FileField(upload_to=get_assignment_dir) question_paper = models.ForeignKey(QuestionPaper, blank=True, null=True) - def get_assignments(self, qp_id, que_id=None, user_id=None): + def get_assignments(self, qp, que_id=None, user_id=None): if que_id and user_id: assignment_files = AssignmentUpload.objects.filter( assignmentQuestion_id=que_id, user_id=user_id, - question_paper_id=qp_id + question_paper=qp ) user_name = User.objects.get(id=user_id) - file_name = user_name.get_full_name().replace(" ", "_") + file_name = user_name.get_full_name() else: assignment_files = AssignmentUpload.objects.filter( - question_paper_id=qp_id + question_paper=qp ) file_name = "%s_Assignment_files" %( diff --git a/yaksh/templates/yaksh/grade_user.html b/yaksh/templates/yaksh/grade_user.html index 69c03c9..311af5c 100644 --- a/yaksh/templates/yaksh/grade_user.html +++ b/yaksh/templates/yaksh/grade_user.html @@ -165,7 +165,7 @@ Status : Passed
    Student answer:
    {% if question.type == "upload" %} {% if user_file_status %} - +
    Assignment File for {{ data.user.get_full_name.title }}
    diff --git a/yaksh/urls.py b/yaksh/urls.py index 445b828..4a96d08 100644 --- a/yaksh/urls.py +++ b/yaksh/urls.py @@ -91,8 +91,8 @@ urlpatterns = [ url(r'^manage/create_demo_course/$', views.create_demo_course), url(r'^manage/courses/download_course_csv/(?P\d+)/$', views.download_course_csv), - url(r'^manage/download/user_assignment/(?P\d+)/(?P\d+)/(?P\d+)/$', + url(r'^manage/download/user_assignment/(?P\d+)/(?P\d+)/(?P\d+)/$', views.download_assignment_file), - url(r'^manage/download/quiz_assignments/(?P\d+)/$', + url(r'^manage/download/quiz_assignments/(?P\d+)/$', views.download_assignment_file) ] diff --git a/yaksh/views.py b/yaksh/views.py index d0735bd..46a2bdd 100644 --- a/yaksh/views.py +++ b/yaksh/views.py @@ -501,14 +501,15 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None): assignment_filename = request.FILES.getlist('assignment') qp = QuestionPaper.objects.get(id=questionpaper_id) for fname in assignment_filename: - if AssignmentUpload.objects.filter( - assignmentQuestion=current_question, - assignmentFile__icontains=fname, user=user, - question_paper=questionpaper_id).exists(): - assign_file = AssignmentUpload.objects.get( - assignmentQuestion=current_question, - assignmentFile__icontains=fname, user=user, - question_paper=questionpaper_id) + assignment_files = AssignmentUpload.objects.filter( + assignmentQuestion=current_question, + assignmentFile__icontains=fname, user=user, + question_paper=questionpaper_id) + if assignment_files.exists(): + assign_file = assignment_files.get( + assignmentQuestion=current_question, + assignmentFile__icontains=fname, user=user, + question_paper=questionpaper_id) os.remove(assign_file.assignmentFile.path) assign_file.delete() AssignmentUpload.objects.create(user=user, @@ -1429,14 +1430,14 @@ def download_course_csv(request, course_id): @login_required -def download_assignment_file(request, questionpaper_id, question_id=None, - user_id=None): +def download_assignment_file(request, quiz_id, question_id=None, user_id=None): user = request.user if not is_moderator(user): raise Http404('You are not allowed to view this page!') + qp = QuestionPaper.objects.get(quiz_id=quiz_id) assignment = AssignmentUpload() - assignment_files, file_name = assignment.get_assignments(questionpaper_id, - question_id, user_id + assignment_files, file_name = assignment.get_assignments(qp, question_id, + user_id ) zipfile_name = string_io() zip_file = zipfile.ZipFile(zipfile_name, "w") -- cgit From f8613224a26f077ffa48ed8420278950293a3a16 Mon Sep 17 00:00:00 2001 From: adityacp Date: Mon, 10 Apr 2017 17:15:13 +0530 Subject: Add test to check assignment uploads --- yaksh/test_models.py | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/yaksh/test_models.py b/yaksh/test_models.py index dbd367b..084c538 100644 --- a/yaksh/test_models.py +++ b/yaksh/test_models.py @@ -1,7 +1,7 @@ import unittest from yaksh.models import User, Profile, Question, Quiz, QuestionPaper,\ QuestionSet, AnswerPaper, Answer, Course, StandardTestCase,\ - StdIOBasedTestCase, FileUpload, McqTestCase + StdIOBasedTestCase, FileUpload, McqTestCase, AssignmentUpload import json from datetime import datetime, timedelta from django.utils import timezone @@ -1034,3 +1034,66 @@ class TestCaseTestCases(unittest.TestCase): exp_data = json.loads(self.answer_data_json) self.assertEqual(actual_data['metadata']['user_answer'], exp_data['metadata']['user_answer']) self.assertEqual(actual_data['test_case_data'], exp_data['test_case_data']) + + +class AssignmentUploadTestCases(unittest.TestCase): + def setUp(self): + self.user = User.objects.get(username="demo_user") + self.user.first_name = "demo" + self.user.last_name = "user" + self.user.save() + course = Course.objects.create(name="Assignment course", + enrollment="Enroll Request", creator=self.user) + self.quiz = Quiz.objects.create(start_date_time=datetime( + 2015, 10, 9, 10, 8, 15, 0, tzinfo=pytz.utc), + end_date_time=datetime(2199, 10, 9, 10, 8, 15, 0, + tzinfo=pytz.utc), + duration=30, active=True, + attempts_allowed=1, time_between_attempts=0, + description='Assignment Quiz', pass_criteria=0, + language='Python', prerequisite=None, + course=course, instructions="Demo Instructions") + + self.questionpaper = QuestionPaper.objects.create(quiz=self.quiz, + total_marks=0.0, + shuffle_questions=True + ) + self.question = Question.objects.create(summary='Assignment', + language='Python', + type='upload', + active=True, + description='Upload a file', + points=1.0, + snippet='', + user=self.user + ) + self.questionpaper.fixed_question_order = "{0}".format(self.question.id) + self.questionpaper.fixed_questions.add(self.question) + file_path = os.path.join(tempfile.gettempdir(), "upload.txt") + self.assignment = AssignmentUpload.objects.create(user=self.user, + assignmentQuestion=self.question, assignmentFile=file_path, + question_paper=self.questionpaper + ) + + def test_get_assignments_for_user_files(self): + assignment_upload_obj = AssignmentUpload() + assignment_files, file_name = assignment_upload_obj.get_assignments( + self.questionpaper, self.question.id, + self.user.id + ) + self.assertIn("upload.txt", assignment_files[0].assignmentFile.name) + self.assertEqual(assignment_files[0].question_paper, self.questionpaper) + actual_file_name = self.user.get_full_name().replace(" ", "_") + file_name = file_name.replace(" ", "_") + self.assertEqual(file_name, actual_file_name) + + def test_get_assignments_for_quiz_files(self): + assignment_upload_obj = AssignmentUpload() + assignment_files, file_name = assignment_upload_obj.get_assignments( + self.questionpaper + ) + self.assertIn("upload.txt", assignment_files[0].assignmentFile.name) + self.assertEqual(assignment_files[0].question_paper, self.questionpaper) + actual_file_name = self.quiz.description.replace(" ", "_") + file_name = file_name.replace(" ", "_") + self.assertIn(actual_file_name, file_name) -- cgit From deaa592f01d5f270abca89c78620af1406fee67c Mon Sep 17 00:00:00 2001 From: adityacp Date: Wed, 19 Apr 2017 12:54:41 +0530 Subject: Change urls, models, views - Add Assignment upload model manager - Change views to update marks for user if updated manually - Change variable names in views - Add url to provide assignment download for student --- yaksh/models.py | 23 ++++++++++++++--------- yaksh/urls.py | 2 ++ yaksh/views.py | 46 +++++++++++++++++++++++++--------------------- 3 files changed, 41 insertions(+), 30 deletions(-) diff --git a/yaksh/models.py b/yaksh/models.py index 5ec3062..6646615 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -1306,12 +1306,8 @@ class AnswerPaper(models.Model): .format(u.first_name, u.last_name, q.description) -############################################################################### -class AssignmentUpload(models.Model): - user = models.ForeignKey(User) - assignmentQuestion = models.ForeignKey(Question) - assignmentFile = models.FileField(upload_to=get_assignment_dir) - question_paper = models.ForeignKey(QuestionPaper, blank=True, null=True) +################################################################################ +class AssignmentUploadManager(models.Manager): def get_assignments(self, qp, que_id=None, user_id=None): if que_id and user_id: @@ -1319,19 +1315,28 @@ class AssignmentUpload(models.Model): assignmentQuestion_id=que_id, user_id=user_id, question_paper=qp ) - user_name = User.objects.get(id=user_id) - file_name = user_name.get_full_name() + file_name = User.objects.get(id=user_id).get_full_name() else: assignment_files = AssignmentUpload.objects.filter( question_paper=qp ) - file_name = "%s_Assignment_files" %( + file_name = "{0}_Assignment_files".format( assignment_files[0].question_paper.quiz.description ) return assignment_files, file_name + +################################################################################ +class AssignmentUpload(models.Model): + user = models.ForeignKey(User) + assignmentQuestion = models.ForeignKey(Question) + assignmentFile = models.FileField(upload_to=get_assignment_dir) + question_paper = models.ForeignKey(QuestionPaper, blank=True, null=True) + objects = AssignmentUploadManager() + + ############################################################################### class TestCase(models.Model): question = models.ForeignKey(Question, blank=True, null=True) diff --git a/yaksh/urls.py b/yaksh/urls.py index 4a96d08..5623eab 100644 --- a/yaksh/urls.py +++ b/yaksh/urls.py @@ -26,6 +26,8 @@ urlpatterns = [ url(r'^enroll_request/(?P\d+)/$', views.enroll_request, name='enroll_request'), url(r'^self_enroll/(?P\d+)/$', views.self_enroll, name='self_enroll'), url(r'^view_answerpaper/(?P\d+)/$', views.view_answerpaper, name='view_answerpaper'), + url(r'^download/user_assignment/(?P\d+)/(?P\d+)/(?P\d+)$', + views.download_assignment_file, name="download_user_assignment"), url(r'^manage/$', views.prof_manage, name='manage'), url(r'^manage/addquestion/$', views.add_question), url(r'^manage/addquestion/(?P\d+)/$', views.add_question), diff --git a/yaksh/views.py b/yaksh/views.py index 46a2bdd..0db1812 100644 --- a/yaksh/views.py +++ b/yaksh/views.py @@ -497,9 +497,11 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None): elif current_question.type == 'upload': # if time-up at upload question then the form is submitted without # validation - if 'assignment' in request.FILES: - assignment_filename = request.FILES.getlist('assignment') - qp = QuestionPaper.objects.get(id=questionpaper_id) + assignment_filename = request.FILES.getlist('assignment') + if not assignment_filename: + msg = "Please upload assignment file" + return show_question(request, current_question, paper, notification=msg) + for fname in assignment_filename: assignment_files = AssignmentUpload.objects.filter( assignmentQuestion=current_question, @@ -514,7 +516,7 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None): assign_file.delete() AssignmentUpload.objects.create(user=user, assignmentQuestion=current_question, assignmentFile=fname, - question_paper=qp + question_paper_id=questionpaper_id ) user_answer = 'ASSIGNMENT UPLOADED' if not current_question.grade_assignment_upload: @@ -1114,11 +1116,11 @@ def grade_user(request, quiz_id=None, user_id=None, attempt_number=None): .values("id") user_details = AnswerPaper.objects\ .get_users_for_questionpaper(questionpaper_id) - quiz_assignment_file_status = AssignmentUpload.objects.filter( + has_quiz_assignments = AssignmentUpload.objects.filter( question_paper_id=questionpaper_id ).exists() context = {"users": user_details, "quiz_id": quiz_id, - "quiz_file_status": quiz_assignment_file_status + "has_quiz_assignments": has_quiz_assignments } if user_id is not None: @@ -1129,7 +1131,7 @@ def grade_user(request, quiz_id=None, user_id=None, attempt_number=None): attempt_number = attempts[0].attempt_number except IndexError: raise Http404('No attempts for paper') - user_assignment_file_status = AssignmentUpload.objects.filter( + has_user_assignments = AssignmentUpload.objects.filter( question_paper_id=questionpaper_id, user_id=user_id ).exists() @@ -1139,17 +1141,17 @@ def grade_user(request, quiz_id=None, user_id=None, attempt_number=None): ) context = {'data': data, "quiz_id": quiz_id, "users": user_details, "attempts": attempts, "user_id": user_id, - "user_file_status": user_assignment_file_status, - "quiz_file_status": quiz_assignment_file_status + "has_user_assignments": has_user_assignments, + "has_quiz_assignments": has_quiz_assignments } if request.method == "POST": papers = data['papers'] for paper in papers: - for question, answers, errors in six.iteritems(paper.get_question_answers()): + for question, answers in six.iteritems(paper.get_question_answers()): marks = float(request.POST.get('q%d_marks' % question.id, 0)) - answers = answers[-1] - answers.set_marks(marks) - answers.save() + answer = answers[-1]['answer'] + answer.set_marks(marks) + answer.save() paper.update_marks() paper.comments = request.POST.get( 'comments_%d' % paper.question_paper.id, 'No comments') @@ -1330,7 +1332,10 @@ def view_answerpaper(request, questionpaper_id): quiz = get_object_or_404(QuestionPaper, pk=questionpaper_id).quiz if quiz.view_answerpaper and user in quiz.course.students.all(): data = AnswerPaper.objects.get_user_data(user, questionpaper_id) - context = {'data': data, 'quiz': quiz} + has_user_assignment = AssignmentUpload.objects.filter(user=user, + question_paper_id=questionpaper_id).exists() + context = {'data': data, 'quiz': quiz, + "has_user_assignment":has_user_assignment} return my_render_to_response('yaksh/view_answerpaper.html', context) else: return my_redirect('/exam/quizzes/') @@ -1432,18 +1437,17 @@ def download_course_csv(request, course_id): @login_required def download_assignment_file(request, quiz_id, question_id=None, user_id=None): user = request.user - if not is_moderator(user): - raise Http404('You are not allowed to view this page!') qp = QuestionPaper.objects.get(quiz_id=quiz_id) - assignment = AssignmentUpload() - assignment_files, file_name = assignment.get_assignments(qp, question_id, + assignment_files, file_name = AssignmentUpload.objects.get_assignments(qp, + question_id, user_id ) zipfile_name = string_io() zip_file = zipfile.ZipFile(zipfile_name, "w") for f_name in assignment_files: - name = f_name.user.get_full_name().replace(" ", "_") - folder_name = os.sep.join((name, os.path.basename( + folder = f_name.user.get_full_name().replace(" ", "_") + sub_folder = f_name.assignmentQuestion.summary.replace(" ", "_") + folder_name = os.sep.join((folder, sub_folder, os.path.basename( f_name.assignmentFile.name)) ) zip_file.write(f_name.assignmentFile.path, folder_name @@ -1452,7 +1456,7 @@ def download_assignment_file(request, quiz_id, question_id=None, user_id=None): zipfile_name.seek(0) response = HttpResponse(content_type='application/zip') response['Content-Disposition'] = '''attachment;\ - filename={0}'''.format( + filename={0}.zip'''.format( file_name.replace(" ", "_") ) response.write(zipfile_name.read()) -- cgit From 7a834136f3f88665605e8eee73be1f9e584e63a6 Mon Sep 17 00:00:00 2001 From: adityacp Date: Wed, 19 Apr 2017 12:57:10 +0530 Subject: Change in Templates - Add additional message for 404 error. - Change grade user template to show label for correct/incorrect answer - Change view answerpaper to provide download facility for students --- yaksh/templates/404.html | 4 +++- yaksh/templates/yaksh/grade_user.html | 13 +++++++++++-- yaksh/templates/yaksh/view_answerpaper.html | 8 +++++++- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/yaksh/templates/404.html b/yaksh/templates/404.html index 8d43ec5..e9d99de 100644 --- a/yaksh/templates/404.html +++ b/yaksh/templates/404.html @@ -1,5 +1,7 @@ {% extends "base.html" %} {% block content %} -{{ exception }} +It seems that you have encountered an error +Type of Error - {{ exception }} +Please contact your administrator {% endblock %} diff --git a/yaksh/templates/yaksh/grade_user.html b/yaksh/templates/yaksh/grade_user.html index 311af5c..1ac4757 100644 --- a/yaksh/templates/yaksh/grade_user.html +++ b/yaksh/templates/yaksh/grade_user.html @@ -46,7 +46,7 @@
    {% endif %} -{% if quiz_file_status %} +{% if has_quiz_assignments %} Download All Assignments @@ -164,12 +164,21 @@ Status : Passed
    Student answer:
    {% if question.type == "upload" %} - {% if user_file_status %} + {% if has_user_assignments %}
    Assignment File for {{ data.user.get_full_name.title }}
    + {% with answers|last as answer%} + {% if answer.answer.correct %} +
    +
    Correct answer
    + {% else %} +
    +
    Incorrect Answer
    + {% endif %} + {% endwith %} {% else %}
    No Assignment submitted by {{ data.user.get_full_name.title }}
    {% endif %} diff --git a/yaksh/templates/yaksh/view_answerpaper.html b/yaksh/templates/yaksh/view_answerpaper.html index 4520ac3..f4c8846 100644 --- a/yaksh/templates/yaksh/view_answerpaper.html +++ b/yaksh/templates/yaksh/view_answerpaper.html @@ -84,7 +84,13 @@
    Student answer:
    {{ answers.0.answer|safe }} -
    + {% if question.type == "upload" and has_user_assignment %} + +
    + Assignment File for {{ data.user.get_full_name.title }} +
    + {% endif %} +
    {% else %} -- cgit From a44a75fef4bfd9a2a15f7bb8ce38d720fe2f411e Mon Sep 17 00:00:00 2001 From: adityacp Date: Wed, 19 Apr 2017 12:59:40 +0530 Subject: Clean AssignementUpload tests in test models --- yaksh/test_models.py | 66 ++++++++++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 35 deletions(-) diff --git a/yaksh/test_models.py b/yaksh/test_models.py index 084c538..9bd8492 100644 --- a/yaksh/test_models.py +++ b/yaksh/test_models.py @@ -68,12 +68,7 @@ def tearDownModule(): Quiz.objects.all().delete() Course.objects.all().delete() QuestionPaper.objects.all().delete() - - que_id_list = ["25", "22", "24", "27"] - for que_id in que_id_list: - dir_path = os.path.join(os.getcwd(), "yaksh", "data","question_{0}".format(que_id)) - if os.path.exists(dir_path): - shutil.rmtree(dir_path) + ############################################################################### class ProfileTestCases(unittest.TestCase): @@ -1038,21 +1033,15 @@ class TestCaseTestCases(unittest.TestCase): class AssignmentUploadTestCases(unittest.TestCase): def setUp(self): - self.user = User.objects.get(username="demo_user") - self.user.first_name = "demo" - self.user.last_name = "user" - self.user.save() - course = Course.objects.create(name="Assignment course", - enrollment="Enroll Request", creator=self.user) - self.quiz = Quiz.objects.create(start_date_time=datetime( - 2015, 10, 9, 10, 8, 15, 0, tzinfo=pytz.utc), - end_date_time=datetime(2199, 10, 9, 10, 8, 15, 0, - tzinfo=pytz.utc), - duration=30, active=True, - attempts_allowed=1, time_between_attempts=0, - description='Assignment Quiz', pass_criteria=0, - language='Python', prerequisite=None, - course=course, instructions="Demo Instructions") + self.user1 = User.objects.get(username="demo_user") + self.user1.first_name = "demo" + self.user1.last_name = "user" + self.user1.save() + self.user2 = User.objects.get(username="demo_user3") + self.user2.first_name = "demo" + self.user2.last_name = "user3" + self.user2.save() + self.quiz = Quiz.objects.get(description="demo quiz 1") self.questionpaper = QuestionPaper.objects.create(quiz=self.quiz, total_marks=0.0, @@ -1065,35 +1054,42 @@ class AssignmentUploadTestCases(unittest.TestCase): description='Upload a file', points=1.0, snippet='', - user=self.user + user=self.user1 ) self.questionpaper.fixed_question_order = "{0}".format(self.question.id) self.questionpaper.fixed_questions.add(self.question) - file_path = os.path.join(tempfile.gettempdir(), "upload.txt") - self.assignment = AssignmentUpload.objects.create(user=self.user, - assignmentQuestion=self.question, assignmentFile=file_path, + file_path1 = os.path.join(tempfile.gettempdir(), "upload1.txt") + file_path2 = os.path.join(tempfile.gettempdir(), "upload2.txt") + self.assignment1 = AssignmentUpload.objects.create(user=self.user1, + assignmentQuestion=self.question, assignmentFile=file_path1, + question_paper=self.questionpaper + ) + self.assignment2 = AssignmentUpload.objects.create(user=self.user2, + assignmentQuestion=self.question, assignmentFile=file_path2, question_paper=self.questionpaper ) def test_get_assignments_for_user_files(self): - assignment_upload_obj = AssignmentUpload() - assignment_files, file_name = assignment_upload_obj.get_assignments( + assignment_files, file_name = AssignmentUpload.objects.get_assignments( self.questionpaper, self.question.id, - self.user.id + self.user1.id ) - self.assertIn("upload.txt", assignment_files[0].assignmentFile.name) - self.assertEqual(assignment_files[0].question_paper, self.questionpaper) - actual_file_name = self.user.get_full_name().replace(" ", "_") + self.assertIn("upload1.txt", assignment_files[0].assignmentFile.name) + self.assertEqual(assignment_files[0].user, self.user1) + actual_file_name = self.user1.get_full_name().replace(" ", "_") file_name = file_name.replace(" ", "_") self.assertEqual(file_name, actual_file_name) def test_get_assignments_for_quiz_files(self): - assignment_upload_obj = AssignmentUpload() - assignment_files, file_name = assignment_upload_obj.get_assignments( + assignment_files, file_name = AssignmentUpload.objects.get_assignments( self.questionpaper ) - self.assertIn("upload.txt", assignment_files[0].assignmentFile.name) - self.assertEqual(assignment_files[0].question_paper, self.questionpaper) + files = [os.path.basename(file.assignmentFile.name) + for file in assignment_files] + question_papers = [file.question_paper for file in assignment_files] + self.assertIn("upload1.txt", files) + self.assertIn("upload2.txt", files) + self.assertEqual(question_papers[0].quiz, self.questionpaper.quiz) actual_file_name = self.quiz.description.replace(" ", "_") file_name = file_name.replace(" ", "_") self.assertIn(actual_file_name, file_name) -- cgit From d2cbe09ff6d356e537ed1845b292b2138b6b8295 Mon Sep 17 00:00:00 2001 From: adityacp Date: Wed, 19 Apr 2017 14:41:45 +0530 Subject: Change views to get distinct quizzes in dashboard --- yaksh/views.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/yaksh/views.py b/yaksh/views.py index c5aeb1c..17274d8 100644 --- a/yaksh/views.py +++ b/yaksh/views.py @@ -288,7 +288,7 @@ def prof_manage(request, msg=None): Q(quiz__course__creator=user) | Q(quiz__course__teachers=user), quiz__is_trial=False - ) + ).distinct() trial_paper = AnswerPaper.objects.filter(user=user, question_paper__quiz__is_trial=True ) @@ -308,9 +308,9 @@ def prof_manage(request, msg=None): for paper in question_papers: answer_papers = AnswerPaper.objects.filter(question_paper=paper) users_passed = AnswerPaper.objects.filter(question_paper=paper, - passed=True).distinct().count() + passed=True).count() users_failed = AnswerPaper.objects.filter(question_paper=paper, - passed=False).distinct().count() + 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, @@ -779,13 +779,13 @@ def monitor(request, quiz_id=None): context_instance=ci) # quiz_id is not None. try: + quiz = get_object_or_404(Quiz, id=quiz_id) + if not quiz.course.is_creator(user) and not quiz.course.is_teacher(user): + raise Http404('This course does not belong to you') q_paper = QuestionPaper.objects.filter(Q(quiz__course__creator=user) | Q(quiz__course__teachers=user), quiz__is_trial=False, quiz_id=quiz_id).distinct() - quiz = get_object_or_404(Quiz, id=quiz_id) - if not quiz.course.is_creator(user) and not quiz.course.is_teacher(user): - raise Http404('This course does not belong to you') except QuestionPaper.DoesNotExist: papers = [] q_paper = None -- cgit