diff options
author | adityacp | 2020-04-08 15:55:59 +0530 |
---|---|---|
committer | adityacp | 2020-04-08 15:55:59 +0530 |
commit | ce3eb1dbbd924003489d01f4e98aba841cd803c0 (patch) | |
tree | 27bdd5eaee82c34094a70a9c5b35626a8d45315d | |
parent | 4802a89acef7567c6a8861daab60924fe862367f (diff) | |
download | online_test-ce3eb1dbbd924003489d01f4e98aba841cd803c0.tar.gz online_test-ce3eb1dbbd924003489d01f4e98aba841cd803c0.tar.bz2 online_test-ce3eb1dbbd924003489d01f4e98aba841cd803c0.zip |
Change templates, views, forms, models
- Allow to test, download and delete single question
- Fix pagination for searching and filtering questions
-rw-r--r-- | online_test/settings.py | 1 | ||||
-rw-r--r-- | yaksh/forms.py | 15 | ||||
-rw-r--r-- | yaksh/models.py | 2 | ||||
-rw-r--r-- | yaksh/static/yaksh/js/question_filter.js | 47 | ||||
-rw-r--r-- | yaksh/static/yaksh/js/show_question.js | 17 | ||||
-rw-r--r-- | yaksh/templates/yaksh/ajax_question_filter.html | 57 | ||||
-rw-r--r-- | yaksh/templates/yaksh/paginator.html | 6 | ||||
-rw-r--r-- | yaksh/templates/yaksh/showquestions.html | 277 | ||||
-rw-r--r-- | yaksh/urls.py | 10 | ||||
-rw-r--r-- | yaksh/views.py | 169 |
10 files changed, 306 insertions, 295 deletions
diff --git a/online_test/settings.py b/online_test/settings.py index 7b9a231..0fda971 100644 --- a/online_test/settings.py +++ b/online_test/settings.py @@ -164,6 +164,7 @@ TEMPLATES = [ 'social_django.context_processors.backends', 'social_django.context_processors.login_redirect', 'django.contrib.messages.context_processors.messages', + 'django.template.context_processors.request', ], 'debug': True, # make this False in production } diff --git a/yaksh/forms.py b/yaksh/forms.py index 52ef75d..d2627d7 100644 --- a/yaksh/forms.py +++ b/yaksh/forms.py @@ -17,9 +17,9 @@ from string import punctuation, digits import pytz from .send_emails import generate_activation_key -languages = (("select", "Select Language"),) + languages +languages = (("", "Select Language"),) + languages -question_types = (("select", "Select Question Type"),) + question_types +question_types = (("", "Select Question Type"),) + question_types test_case_types = ( ("standardtestcase", "Standard Testcase"), @@ -357,11 +357,14 @@ class QuestionFilterForm(forms.Form): ) self.fields['marks'].required = False language = forms.CharField( - max_length=8, widget=forms.Select(choices=languages, - attrs={'class': 'custom-select'})) + max_length=8, widget=forms.Select( + choices=languages, attrs={'class': 'custom-select'}), + required=False + ) question_type = forms.CharField( - max_length=8, widget=forms.Select(choices=question_types, - attrs={'class': 'custom-select'}) + max_length=8, widget=forms.Select( + choices=question_types, attrs={'class': 'custom-select'}), + required=False ) diff --git a/yaksh/models.py b/yaksh/models.py index 52a0414..5d4d453 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -1385,7 +1385,7 @@ class Question(models.Model): testcases.append(case.get_field_value()) q_dict['testcase'] = testcases q_dict['files'] = file_names - q_dict['tags'] = [tags.tag.name for tags in q_dict['tags']] + q_dict['tags'] = [tag.name for tag in q_dict['tags']] questions_dict.append(q_dict) question._add_yaml_to_zip(zip_file, questions_dict) return zip_file_name diff --git a/yaksh/static/yaksh/js/question_filter.js b/yaksh/static/yaksh/js/question_filter.js deleted file mode 100644 index aa3a229..0000000 --- a/yaksh/static/yaksh/js/question_filter.js +++ /dev/null @@ -1,47 +0,0 @@ -$(document).ready(function(){ - $question_type = $("#id_question_type"); - $marks = $("#id_marks"); - $language = $("#id_language"); - - function question_filter() { - $.ajax({ - url: "/exam/ajax/questions/filter/", - type: "POST", - data: { - question_type: $question_type.val(), - marks: $marks.val(), - language: $language.val() - }, - dataType: "html", - success: function(output) { - var questions = $(output).filter("#questions").html(); - $("#filtered-questions").html(questions); - } - }); - } - - $question_type.change(function() { - question_filter() - }); - - $language.change(function() { - question_filter() - }); - - $marks.change(function() { - question_filter() - }); - - $("#checkall").change(function(){ - if($(this).prop("checked")) { - $("#filtered-questions input:checkbox").each(function(index, element) { - $(this).prop('checked', true); - }); - } - else { - $("#filtered-questions input:checkbox").each(function(index, element) { - $(this).prop('checked', false); - }); - } - }); -});
\ No newline at end of file diff --git a/yaksh/static/yaksh/js/show_question.js b/yaksh/static/yaksh/js/show_question.js index e6825a0..d7b6a44 100644 --- a/yaksh/static/yaksh/js/show_question.js +++ b/yaksh/static/yaksh/js/show_question.js @@ -47,7 +47,18 @@ function append_tag(tag){ tag_name.value = tag.value; } } -$(document).ready(function() - { - $("#questions-table").tablesorter({sortList: [[0,0], [4,0]]}); +$(document).ready(function() { + $("#questions-table").tablesorter({}); + $("#checkall").change(function(){ + if($(this).prop("checked")) { + $("#filtered-questions input:checkbox").each(function(index, element) { + $(this).prop('checked', true); + }); + } + else { + $("#filtered-questions input:checkbox").each(function(index, element) { + $(this).prop('checked', false); + }); + } }); +}); diff --git a/yaksh/templates/yaksh/ajax_question_filter.html b/yaksh/templates/yaksh/ajax_question_filter.html deleted file mode 100644 index 18f14ff..0000000 --- a/yaksh/templates/yaksh/ajax_question_filter.html +++ /dev/null @@ -1,57 +0,0 @@ -<div id="questions"> - <script> - $(document).ready(function(){ - $("#checkall").change(function(){ - if($(this).prop("checked")) { - $("#filtered-questions input:checkbox").each(function(index, element) { - $(this).prop('checked', true); - }); - } - else { - $("#filtered-questions input:checkbox").each(function(index, element) { - $(this).prop('checked', false); - }); - } - }); - }); - </script> - <br> - <a class="btn btn-lg btn-success" href="{% url 'yaksh:add_question' %}"> - <i class="fa fa-plus-circle"></i> Add Question - </a> - <br><br> - {% if questions %} - {% include "yaksh/paginator.html" %} - - <h5 class="highlight"><input type="checkbox" id="checkall"> - Select All - </h5> - <ul class="inputs-list"> - <table id="questions-table" class="tablesorter table table table-striped"> - <thead> - <tr> - <th> Select </th> - <th> Summary </th> - <th> Language </th> - <th> Type </th> - <th> Marks </th> - </tr> - </thead> - <tbody> - {% for question in questions %} - <tr> - <td> - <input type="checkbox" name="question" value="{{ question.id }}"> - </td> - <td><a href="{% url 'yaksh:add_question' question.id %}">{{question.summary|capfirst}}</a></td> - <td>{{question.language|capfirst}}</td> - <td>{{question.type|capfirst}}</td> - <td>{{question.points}}</td> - </tr> - {% endfor %} - </tbody> - </table> - </ul> - {% include "yaksh/paginator.html" %} - {% endif %} -</div> diff --git a/yaksh/templates/yaksh/paginator.html b/yaksh/templates/yaksh/paginator.html index 5f0df7a..c634d5c 100644 --- a/yaksh/templates/yaksh/paginator.html +++ b/yaksh/templates/yaksh/paginator.html @@ -1,7 +1,7 @@ <ul class="pagination pagination"> {% if objects.has_previous %} <li class="page-item"> - <a class="page-link" href="?page=1" aria-label="Previous"> + <a class="page-link" href="?page=1{% if request.GET.question_type %}&question_type={{ request.GET.question_type }}{% endif %}{% if request.GET.language %}&language={{ request.GET.language }}{% endif %}{% if request.GET.marks %}&marks={{ request.GET.marks }}{% endif %}{% if request.GET.question_tags %}&question_tags={{ request.GET.question_tags }}{% endif %}" aria-label="Previous"> <span aria-hidden="true"> <i class="fa fa-angle-double-left"></i> </span> @@ -16,13 +16,13 @@ <span class="page-link">{{ n }}<span class="sr-only">(current)</span></span> </li> {% elif n > objects.number|add:'-5' and n < objects.number|add:'5' %} - <li class="page-item"><a class="page-link" href="?page={{ n }}">{{ n }}</a></li> + <li class="page-item"><a class="page-link" href="?page={{ n }}{% if request.GET.question_type %}&question_type={{ request.GET.question_type }}{% endif %}{% if request.GET.language %}&language={{ request.GET.language }}{% endif %}{% if request.GET.marks %}&marks={{ request.GET.marks }}{% endif %}{% if request.GET.question_tags %}&question_tags={{ request.GET.question_tags }}{% endif %}">{{ n }}</a></li> {% endif %} {% endfor %} {% if objects.has_next %} <li class="page-item"> - <a class="page-link" href="?page={{ objects.paginator.num_pages }}" aria-label="Next"> + <a class="page-link" href="?page={{ objects.paginator.num_pages }}{% if request.GET.question_type %}&question_type={{ request.GET.question_type }}{% endif %}{% if request.GET.language %}&language={{ request.GET.language }}{% endif %}{% if request.GET.marks %}&marks={{ request.GET.marks }}{% endif %}{% if request.GET.question_tags %}&question_tags={{ request.GET.question_tags }}{% endif %}" aria-label="Next"> <span aria-hidden="true"> <i class="fa fa-angle-double-right"></i> </span> diff --git a/yaksh/templates/yaksh/showquestions.html b/yaksh/templates/yaksh/showquestions.html index e0cd529..6f05a0b 100644 --- a/yaksh/templates/yaksh/showquestions.html +++ b/yaksh/templates/yaksh/showquestions.html @@ -7,154 +7,153 @@ {% block script %} <script type="text/javascript" src="{% static 'yaksh/js/show_question.js' %}"></script> -<script type="text/javascript" src="{% static 'yaksh/js/question_filter.js' %}"></script> <script type="text/javascript" src="{% static 'yaksh/js/jquery.tablesorter.min.js' %}"></script> {% endblock %} {% block content %} -<div class="container"> - <!-- Side bar --> - <div class="nav nav-pills" role="tablist" aria-orientation="vertical"> - <a href="#show" id="showbar" class="nav-link active" data-toggle="pill" role="tab" aria-controls="show" aria-selected="true"> Show all Questions</a> - <a href="#updown" id="updownbar" class="nav-link" data-toggle="pill" role="tab" aria-controls="updown" aria-selected="false" > Upload Questions</a> - </div> - <!-- End of side bar --> - <div class="tab-content"> + <div class="container-fluid"> + <div class="nav nav-pills" role="tablist" aria-orientation="vertical"> + <a href="#show" id="showbar" class="nav-link active" data-toggle="pill" role="tab" aria-controls="show" aria-selected="true"> Show all Questions</a> + <a href="#updown" id="updownbar" class="nav-link" data-toggle="pill" role="tab" aria-controls="updown" aria-selected="false" > Upload Questions</a> + </div> <br> - <!-- Upload Questions --> - <div id="updown" class="card tab-pane fade" role="tabpanel" aria-labelledby="updownbar"> - <div class="col" role="alert"> - <p>You can upload question files the following ways - - <li><b><u>Yaml File</u></b> - <p>One can upload Yaml file with extensions .yaml or .yml. Please note - that you cannot upload files associated to a question. Yaml file can - have any name. - </p> - </li> - <li><b><u>Zip File</u></b> - <p> One can also upload zip with the following zip structure - </p> - <pre> - .zip - |-- .yaml or .yml - |-- .yaml or .yml - |-- folder1 - | |-- Files required by questions - |-- folder2 - | |-- Files required by questions - </pre> - </li> - </p> - </div> - <div class="card-body"> - <form action="" method="post" enctype="multipart/form-data"> - {% csrf_token %} - <div class="form-group col-md-6"> - <a class="btn btn-info" href="{% url 'yaksh:download_yaml_template' %}"> - <i class="fa fa-download"></i> Download Template</a> - <br><br> - <h4> Or </h4> - <br> - <div class="input-group mb-3"> - <div class="custom-file"> - {{ upload_form }} - <label class="custom-file-label" for="id_file"> - Choose file - </label> - </div> - <div class="input-group-append"> - <button class="btn btn-outline-primary" type="submit" name="upload" value="upload"><i class="fa fa-upload"></i> Upload File</button> - </div> - </div> - </div> - <script> - $('#id_file').on('change',function(){ - //get the file name - var fileName = $(this).val(); - //replace the "Choose a file" label - $(this).next('.custom-file-label').html(fileName); - }) - </script> - </form> + <div class="tab-content"> + <!-- Upload Questions --> + <div id="updown" class="card tab-pane fade" role="tabpanel" aria-labelledby="updownbar"> + <div class="col" role="alert"> + <p>You can upload question files the following ways - + <li><b><u>Yaml File</u></b> + <p>One can upload Yaml file with extensions .yaml or .yml. Please note + that you cannot upload files associated to a question. Yaml file can + have any name. + </p> + </li> + <li><b><u>Zip File</u></b> + <p> One can also upload zip with the following zip structure - </p> + <pre> + .zip + |-- .yaml or .yml + |-- .yaml or .yml + |-- folder1 + | |-- Files required by questions + |-- folder2 + | |-- Files required by questions + </pre> + </li> + </p> + </div> + <div class="card-body"> + <form action="" method="post" enctype="multipart/form-data"> + {% csrf_token %} + <div class="form-group col-md-6"> + <a class="btn btn-info" href="{% url 'yaksh:download_yaml_template' %}"> + <i class="fa fa-download"></i> Download Template</a> + <br><br> + <h4> Or </h4> + <br> + <div class="input-group mb-3"> + <div class="custom-file"> + {{ upload_form }} + <label class="custom-file-label" for="id_file"> + Choose file + </label> + </div> + <div class="input-group-append"> + <button class="btn btn-outline-primary" type="submit" name="upload" value="upload"><i class="fa fa-upload"></i> Upload File</button> + </div> + </div> + </div> + <script> + $('#id_file').on('change',function(){ + //get the file name + var fileName = $(this).val(); + //replace the "Choose a file" label + $(this).next('.custom-file-label').html(fileName); + }) + </script> + </form> + </div> </div> - </div> - <!-- End of upload questions --> + <!-- End of upload questions --> - <!-- Show questions --> - <div id="show" class="tab-pane fade show active" role="tabpanel" aria-labelledby="showbar"> - {% if messages %} - {% for message in messages %} - <div class="alert alert-dismissible alert-info"> - <button type="button" class="close" data-dismiss="alert"> - <i class="fa fa-close"></i> - </button> - <strong>{{ message }}</strong> - </div> - {% endfor %} - {% endif %} - <form name=frm action="" method="post"> + <div id="show" class="tab-pane fade show active" role="tabpanel" aria-labelledby="showbar"> + {% if messages %} + {% for message in messages %} + <div class="alert alert-dismissible alert-info"> + <button type="button" class="close" data-dismiss="alert"> + <i class="fa fa-close"></i> + </button> + <strong>{{ message }}</strong> + </div> + {% endfor %} + {% endif %} <div class="card"> <div class="card-body"> - <!-- Filtering Questions --> - <div id="selectors"> - <h4>Filters Questions: </h4> - <div class="dropdown"> - <div class="col-md-4"> - {{ form.question_type }} - </div> - <div class="col-md-4"> - {{ form.language }} - </div> - <div class="col-md-4"> - {{ form.marks }} - </div> + <!-- Filter Questions --> + <h4>Filters Questions: </h4> + <form method="GET" action="{% url 'yaksh:questions_filter' %}"> + + <div class="row"> + <div class="col-md-4">{{ form.question_type }}</div> + <div class="col-md-4">{{ form.language }}</div> + <div class="col-md-4">{{ form.marks }}</div> + <br><br> + <div class="col"> + <button class="btn btn-outline-success"> + <i class="fa fa-filter"></i> Filter + </button> + </div> </div> - </div> + </form> + <!-- End Filter Questions --> <hr> - <h4 >Or Search using Tags: </h4> - <!-- Searching Tags --> - {% csrf_token %} - <div class="col-md-14"> - <div class="input-group"> - <div class="col-md-6"> + <!-- Search by Tags --> + <h4 >Search using Tags: </h4> + <div class="row"> + <div class="col"> + <form method="GET" action="{% url 'yaksh:search_questions_by_tags' %}"> <div class="input-group"> - <div class="input-group-prepend"> - <span class="input-group-text" id="basic-addon1">Search Questions</span> - </div> - <input type="text" name="question_tags" id="question_tags" class="form-control" type="search" placeholder="Search using comma separated Tags"> + <input type="text" name="question_tags" id="question_tags" class="form-control" type="search" placeholder="Search questions using comma separated Tags"> <span class="input-group-append"> - <button class="btn btn-outline-secondary" type="submit"><i class="fa fa-search"></i></button> + <button class="btn btn-outline-success" type="submit"> + <i class="fa fa-search"></i> Search + </button> </span> </div> - </div> - <div class="col-md-6"> - <select class="form-control" id="sel1" onchange="append_tag(this);"> - {% if all_tags %} - <option value="" disabled selected>Available Tags</option> - {% for tag in all_tags %} - <option> - {{tag}} - </option> - {% endfor %} - {% else %} - <option value="" disabled selected>No Available Tags</option> - {% endif %} - </select> - </div> - <br><br> - <div class="col-md-6"> - <a class="btn btn-primary" href="{% url 'yaksh:show_questions' %}"> - Clear Filters - </a> - </div> + </form> + </div> + <div class="col"> + <select class="form-control" id="sel1" onchange="append_tag(this);"> + {% if all_tags %} + <option value="" disabled selected>Available Tags</option> + {% for tag in all_tags %} + <option> + {{tag}} + </option> + {% endfor %} + {% else %} + <option value="" disabled selected>No Available Tags</option> + {% endif %} + </select> </div> </div> + <br> + <!-- End Search by Tags --> + <a class="btn btn-outline-danger" href="{% url 'yaksh:show_questions' %}"> + <i class="fa fa-times"></i> Clear + </a> </div> + <!-- End Card body --> </div> + <!-- End card filters and search --> + </div> + <form name=frm action="{% url 'yaksh:show_questions' %}" method="post"> + {% csrf_token %} <div id="filtered-questions"> <br> <a class="btn btn-lg btn-success" href="{% url 'yaksh:add_question' %}"> <i class="fa fa-plus-circle"></i> Add Question</a> - {% if questions %} + {% if objects %} <div> <br> {% include "yaksh/paginator.html" %} @@ -163,24 +162,38 @@ <div class="table-wrapper-2"> <table id="questions-table" class="tablesorter table table-striped table-responsive-sm"> <thead> - <tr class="yakshred"> + <tr> <th> Select </th> + <th> Sr No. </th> <th> Summary <i class="fa fa-sort"></i> </th> <th> Language <i class="fa fa-sort"></i> </th> <th> Type <i class="fa fa-sort"></i> </th> <th> Marks <i class="fa fa-sort"></i> </th> + <th>Test</th> + <th>Download</th> + <th>Delete</th> </tr> </thead> <tbody> - {% for question in questions %} + {% for question in objects %} <tr> <td> <input type="checkbox" name="question" value="{{ question.id }}"> </td> + <td>{{forloop.counter}}</td> <td><a href="{% url 'yaksh:add_question' question.id %}">{{question.summary|capfirst}}</a></td> <td>{{question.language|capfirst}}</td> <td>{{question.type|capfirst}}</td> <td>{{question.points}}</td> + <td> + <a href="{% url 'yaksh:test_question' question.id %}" class="btn btn-info"> + Test + </a> + </td> + <td><a href="{% url 'yaksh:download_question' question.id %}" class="btn btn-primary"> + <i class="fa fa-download"></i> Download</a></td> + <td><a href="{% url 'yaksh:delete_question' question.id %}" class="btn btn-danger" onclick="return confirm('Are you sure you want to delete {{question.summary|capfirst}}?')"> + <i class="fa fa-trash"></i> Delete</a></td> </tr> {% endfor %} </tbody> @@ -191,23 +204,21 @@ {% else %} <br><br> <div class="alert alert-info"> - <center><h3>No Questions created</h3></center> + <center><h3>No Questions found</h3></center> </div> {% endif %} </div> <br> <center> - {% if questions %} + {% if objects %} <button class="btn btn-lg btn-primary" type="submit" name='download' value='download'><i class="fa fa-download"></i> Download Selected</button> <button class="btn btn-lg btn-primary" type="submit" name="test" value="test">Test Selected</button> <button class="btn btn-lg btn-danger" type="submit" onClick="return confirm_delete(frm);" name='delete' value='delete'> <i class="fa fa-trash"></i> Delete Selected</button> {% endif %} </center> - </form> - </div> - <!-- End of Show questions --> + </form> </div> -</div> + </div> {% endblock %} diff --git a/yaksh/urls.py b/yaksh/urls.py index bdc3330..6085c51 100644 --- a/yaksh/urls.py +++ b/yaksh/urls.py @@ -124,7 +124,7 @@ urlpatterns = [ views.reject, {'was_enrolled': True}, name="reject_user"), url(r'manage/toggle_status/(?P<course_id>\d+)/$', views.toggle_course_status, name="toggle_course_status"), - url(r'^ajax/questions/filter/$', views.ajax_questions_filter, + url(r'^questions/filter$', views.questions_filter, name="questions_filter"), url(r'^editprofile/$', views.edit_profile, name='edit_profile'), url(r'^viewprofile/$', views.view_profile, name='view_profile'), @@ -205,4 +205,12 @@ urlpatterns = [ views.course_teachers, name="course_teachers"), url(r'^manage/download/course/progress/(?P<course_id>\d+)', views.download_course_progress, name="download_course_progress"), + url(r'^manage/question/download/(?P<question_id>\d+)', + views.download_question, name="download_question"), + url(r'^manage/question/test/(?P<question_id>\d+)', + views.test_question, name="test_question"), + url(r'^manage/question/delete/(?P<question_id>\d+)', + views.delete_question, name="delete_question"), + url(r'^manage/search/questions', views.search_questions_by_tags, + name="search_questions_by_tags"), ] diff --git a/yaksh/views.py b/yaksh/views.py index 9efcbe9..33a8680 100644 --- a/yaksh/views.py +++ b/yaksh/views.py @@ -1329,36 +1329,6 @@ def monitor(request, quiz_id=None, course_id=None): return my_render_to_response(request, 'yaksh/monitor.html', context) -@csrf_exempt -def ajax_questions_filter(request): - """Ajax call made when filtering displayed questions.""" - - user = request.user - filter_dict = {"user_id": user.id, "active": True} - question_type = request.POST.get('question_type') - marks = request.POST.get('marks') - language = request.POST.get('language') - if question_type: - filter_dict['type'] = str(question_type) - - if marks: - filter_dict['points'] = marks - - if language: - filter_dict['language'] = str(language) - questions = Question.objects.get_queryset().filter( - **filter_dict).order_by('id') - paginator = Paginator(questions, 30) - page = request.GET.get('page') - questions = paginator.get_page(page) - return my_render_to_response( - request, 'yaksh/ajax_question_filter.html', { - 'questions': questions, - 'objects': questions - } - ) - - def _get_questions(user, question_type, marks): if question_type is None and marks is None: return None @@ -1385,12 +1355,16 @@ def _remove_already_present(questionpaper_id, questions): return questions -def _get_questions_from_tags(question_tags, user, active=True): +def _get_questions_from_tags(question_tags, user, active=True, questions=None): search_tags = [] for tags in question_tags: search_tags.extend(re.split('[; |, |\*|\n]', tags)) - return Question.objects.filter(tags__name__in=search_tags, - user=user, active=active).distinct() + if questions: + search = questions.filter(tags__name__in=search_tags) + else: + search = Question.objects.get_queryset().filter( + tags__name__in=search_tags, user=user, active=active).distinct() + return search @login_required @@ -1536,7 +1510,7 @@ def show_all_questions(request): raise Http404("You are not allowed to view this page !") questions = Question.objects.get_queryset().filter( - user_id=user.id, active=True).order_by('id') + user_id=user.id, active=True).order_by('-id') form = QuestionFilterForm(user=user) user_tags = questions.values_list('tags', flat=True).distinct() all_tags = Tag.objects.filter(id__in=user_tags) @@ -1544,11 +1518,8 @@ def show_all_questions(request): paginator = Paginator(questions, 30) page = request.GET.get('page') questions = paginator.get_page(page) - context['questions'] = questions context['objects'] = questions context['all_tags'] = all_tags - context['papers'] = [] - context['question'] = None context['form'] = form context['upload_form'] = upload_form @@ -1576,7 +1547,7 @@ def show_all_questions(request): questions = questions_file.read() message = ques.load_questions(questions, user) else: - message = "Please Upload a ZIP file" + message = "Please Upload a ZIP file or YAML file" if request.POST.get('download') == 'download': question_ids = request.POST.getlist('question') @@ -1600,21 +1571,131 @@ def show_all_questions(request): user, False, question_ids, None) trial_paper.update_total_marks() trial_paper.save() - return my_redirect("/exam/start/1/{0}/{1}/{2}".format( - trial_module.id, trial_paper.id, trial_course.id)) + return my_redirect(reverse("yaksh:start_quiz", + args=[1, trial_module.id, trial_paper.id, trial_course.id] + )) else: message = "Please select atleast one question to test" - if request.POST.get('question_tags'): - question_tags = request.POST.getlist("question_tags") - search_result = _get_questions_from_tags(question_tags, user) - context['questions'] = search_result messages.info(request, message) return my_render_to_response(request, 'yaksh/showquestions.html', context) @login_required @email_verified +def questions_filter(request): + """Filter questions by type, language or marks.""" + + user = request.user + if not is_moderator(user): + raise Http404('You are not allowed to view this page!') + + questions = Question.objects.get_queryset().filter( + user_id=user.id, active=True).order_by('-id') + form = QuestionFilterForm(user=user) + user_tags = questions.values_list('tags', flat=True).distinct() + all_tags = Tag.objects.filter(id__in=user_tags) + form = QuestionFilterForm(user=user) + upload_form = UploadFileForm() + filter_dict = {} + question_type = request.GET.get('question_type') + marks = request.GET.get('marks') + language = request.GET.get('language') + if question_type: + filter_dict['type'] = str(question_type) + if marks: + filter_dict['points'] = marks + if language: + filter_dict['language'] = str(language) + questions = questions.filter(**filter_dict).order_by('-id') + paginator = Paginator(questions, 30) + page = request.GET.get('page') + questions = paginator.get_page(page) + context = {'form': form, 'upload_form': upload_form, + 'all_tags': all_tags, 'objects': questions} + return my_render_to_response( + request, 'yaksh/showquestions.html', context + ) + + +@login_required +@email_verified +def delete_question(request, question_id): + user = request.user + if not is_moderator(user): + raise Http404("You are not allowed to view this page !") + + question = get_object_or_404(Question, pk=question_id) + question.active = False + question.save() + messages.success(request, "Deleted Question Successfully") + + return my_redirect(reverse("yaksh:show_questions")) + + +@login_required +@email_verified +def download_question(request, question_id): + user = request.user + if not is_moderator(user): + raise Http404("You are not allowed to view this page !") + + question = Question() + zip_file = question.dump_questions([question_id], user) + response = HttpResponse(content_type='application/zip') + response['Content-Disposition'] = dedent( + '''attachment; filename={0}_question.zip'''.format(user) + ) + zip_file.seek(0) + response.write(zip_file.read()) + return response + + +@login_required +@email_verified +def test_question(request, question_id): + user = request.user + if not is_moderator(user): + raise Http404("You are not allowed to view this page !") + + trial_paper, trial_course, trial_module = test_mode( + user, False, [question_id], None) + trial_paper.update_total_marks() + trial_paper.save() + return my_redirect( + reverse("yaksh:start_quiz", + args=[1, trial_module.id, trial_paper.id, trial_course.id] + ) + ) + +@login_required +@email_verified +def search_questions_by_tags(request): + user = request.user + if not is_moderator(user): + raise Http404("You are not allowed to view this page !") + + questions = Question.objects.get_queryset().filter( + user_id=user.id, active=True).order_by('-id') + form = QuestionFilterForm(user=user) + user_tags = questions.values_list('tags', flat=True).distinct() + all_tags = Tag.objects.filter(id__in=user_tags) + form = QuestionFilterForm(user=user) + upload_form = UploadFileForm() + question_tags = request.GET.getlist("question_tags") + questions = _get_questions_from_tags( + question_tags, user, questions=questions + ) + paginator = Paginator(questions, 30) + page = request.GET.get('page') + questions = paginator.get_page(page) + context = {'form': form, 'upload_form': upload_form, + 'all_tags': all_tags, 'objects': questions} + return my_render_to_response(request, 'yaksh/showquestions.html', context) + + +@login_required +@email_verified def user_data(request, user_id, questionpaper_id=None, course_id=None): """Render user data.""" current_user = request.user |