summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--online_test/settings.py1
-rw-r--r--yaksh/forms.py15
-rw-r--r--yaksh/models.py2
-rw-r--r--yaksh/static/yaksh/js/question_filter.js47
-rw-r--r--yaksh/static/yaksh/js/show_question.js17
-rw-r--r--yaksh/templates/yaksh/ajax_question_filter.html57
-rw-r--r--yaksh/templates/yaksh/paginator.html6
-rw-r--r--yaksh/templates/yaksh/showquestions.html277
-rw-r--r--yaksh/urls.py10
-rw-r--r--yaksh/views.py169
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>&nbsp;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>&nbsp;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>&nbsp;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>&nbsp;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>&nbsp;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>&nbsp;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>&nbsp;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>&nbsp;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>&nbsp;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&nbsp;<i class="fa fa-sort"></i> </th>
<th> Language&nbsp;<i class="fa fa-sort"></i> </th>
<th> Type&nbsp;<i class="fa fa-sort"></i> </th>
<th> Marks&nbsp;<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>&nbsp;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>&nbsp;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>&nbsp;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>&nbsp;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