summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorankitjavalkar2016-04-26 19:37:42 +0530
committerankitjavalkar2016-05-05 19:19:00 +0530
commitc557e19470a389aaac569516ed56e1c5b453fd88 (patch)
tree9e4ac79d2ece44f434aa0625d58e198e6875102c
parent5684b1b19fcb383f494f0bfc04ad1bb760abce74 (diff)
downloadonline_test-c557e19470a389aaac569516ed56e1c5b453fd88.tar.gz
online_test-c557e19470a389aaac569516ed56e1c5b453fd88.tar.bz2
online_test-c557e19470a389aaac569516ed56e1c5b453fd88.zip
Add views, forms and templates (with JS) for new test cases:
- Add a view and template to list out test cases for particular question - Add a view and template to add/edit test cases
-rw-r--r--yaksh/forms.py22
-rw-r--r--yaksh/models.py44
-rw-r--r--yaksh/static/yaksh/js/show_testcase.js24
-rw-r--r--yaksh/templates/yaksh/add_question.html15
-rw-r--r--yaksh/templates/yaksh/add_testcase.html32
-rw-r--r--yaksh/templates/yaksh/show_testcase.html31
-rw-r--r--yaksh/views.py104
7 files changed, 228 insertions, 44 deletions
diff --git a/yaksh/forms.py b/yaksh/forms.py
index 1375d10..9ffef5e 100644
--- a/yaksh/forms.py
+++ b/yaksh/forms.py
@@ -1,8 +1,10 @@
from django import forms
-from yaksh.models import Profile, Quiz, Question, TestCase, Course
+from yaksh.models import Profile, Quiz, Question, TestCase, Course, StandardTestCase, StdoutBasedTestCase
from django.contrib.auth import authenticate
from django.contrib.auth.models import User
+from django.contrib.contenttypes.models import ContentType
+
from taggit.managers import TaggableManager
from taggit.forms import TagField
from django.forms.models import inlineformset_factory
@@ -30,8 +32,8 @@ question_types = (
test_case_types = (
("standardtestcase", "Standard Testcase"),
- # ("argument_based", "Multiple Correct Choices"),
("stdoutbasedtestcase", "Stdout Based Testcase"),
+ ("mcqtestcase", "MCQ Testcase"),
)
UNAME_CHARS = letters + "._" + digits
@@ -41,6 +43,22 @@ attempts = [(i, i) for i in range(1, 6)]
attempts.append((-1, 'Infinite'))
days_between_attempts = ((j, j) for j in range(401))
+def get_object_form(model, exclude_fields=None):
+ ctype = ContentType.objects.get(app_label="yaksh", model=model)
+ # ctype = ContentType.objects.get(pk=type_id)
+ model_class = ctype.model_class()
+ class _ObjectForm(forms.ModelForm):
+ # def __init__(self, *args, **kwargs):
+ # if "question" in kwargs:
+ # question = kwargs.pop("question")
+ # else:
+ # question = None
+ # self.fields["question"] = question
+ class Meta:
+ model = model_class
+ exclude = exclude_fields
+ return _ObjectForm
+
class UserRegisterForm(forms.Form):
"""A Class to create new form for User's Registration.
diff --git a/yaksh/models.py b/yaksh/models.py
index fd60036..b1a53f0 100644
--- a/yaksh/models.py
+++ b/yaksh/models.py
@@ -6,6 +6,7 @@ from collections import Counter
from django.db import models
from django.contrib.auth.models import User
from django.forms.models import model_to_dict
+from django.contrib.contenttypes.models import ContentType
from taggit.managers import TaggableManager
@@ -34,7 +35,7 @@ enrollment_methods = (
test_case_types = (
("standardtestcase", "Standard Testcase"),
("stdoutbasedtestcase", "Stdout Based Testcase"),
- # ("mcqtestcase", "MCQ Testcase"),
+ ("mcqtestcase", "MCQ Testcase"),
)
attempts = [(i, i) for i in range(1, 6)]
@@ -226,11 +227,17 @@ class Question(models.Model):
question_data = {}
test_case_data = []
- test_cases = self.testcase_set.all()
+ test_cases = self.get_test_cases()
+
for test in test_cases:
- test_case_child_instance = test.get_child_instance(self.test_case_type)
- test_case_instance_dict = test_case_child_instance.get_instance_as_dict()
- test_case_data.append(test_case_field_value)
+ test_case_as_dict = test.get_field_value()
+ test_case_data.append(test_case_as_dict)
+
+ # test_cases = self.testcase_set.all()
+ # for test in test_cases:
+ # test_case_child_instance = test.get_child_instance(self.test_case_type)
+ # test_case_instance_dict = test_case_child_instance.get_instance_as_dict()
+ # test_case_data.append(test_case_field_value)
question_data['test_case_data'] = test_case_data
question_data['user_answer'] = user_answer
@@ -257,6 +264,18 @@ class Question(models.Model):
question['user'] = user
Question.objects.get_or_create(**question)
+ def get_test_cases(self):
+ test_case_ctype = ContentType.objects.get(app_label="yaksh", model=self.test_case_type)
+ test_cases = test_case_ctype.get_all_objects_for_this_type(question=self)
+
+ return test_cases
+
+ def get_test_case(self, test_case_id):
+ test_case_ctype = ContentType.objects.get(app_label="yaksh", model=self.test_case_type)
+ test_case = test_case_ctype.get_object_for_this_type(question=self, id=test_case_id)
+
+ return test_case
+
def __unicode__(self):
return self.summary
@@ -772,8 +791,9 @@ class AssignmentUpload(models.Model):
class TestCase(models.Model):
question = models.ForeignKey(Question, blank=True, null = True)
- def get_child_instance(self, type):
- return getattr(self, type)
+ # def get_child_instance(self, type):
+ # return getattr(self, type)
+
class StandardTestCase(TestCase):
test_case = models.TextField(blank=True)
@@ -781,6 +801,9 @@ class StandardTestCase(TestCase):
def get_field_value(self):
return {"test_case": self.test_case}
+ def __unicode__(self):
+ return u'Question: {0} | Test Case: {1}'.format(self.question, self.test_case)
+
class StdoutBasedTestCase(TestCase):
expected_output = models.TextField(blank=True)
@@ -788,9 +811,16 @@ class StdoutBasedTestCase(TestCase):
def get_field_value(self):
return {"expected_output": self.expected_output}
+ def __unicode__(self):
+ return u'Question: {0} | Exp. Output: {1}'.format(self.question, self.expected_output)
+
+
class McqTestCase(TestCase):
options = models.TextField()
correct = models.BooleanField(default=False)
def get_field_value(self):
return {"options": self.options, "correct": self.correct}
+
+ def __unicode__(self):
+ return u'Question: {0} | Correct: {1}'.format(self.question, self.correct)
diff --git a/yaksh/static/yaksh/js/show_testcase.js b/yaksh/static/yaksh/js/show_testcase.js
new file mode 100644
index 0000000..71be9dc
--- /dev/null
+++ b/yaksh/static/yaksh/js/show_testcase.js
@@ -0,0 +1,24 @@
+function confirm_delete(frm)
+{
+ var n=0;
+ test_case = document.getElementsByName('test_case');
+ for (var i =0;i<test_case.length;i++)
+ {
+ if (test_case[i].checked == false)
+ n = n + 1 ;
+ }
+ if(n==test_case.length)
+ {
+ alert("Please Select at least one test case");
+ return false;
+ }
+ var r = confirm("Are you Sure ?");
+ if(r==false)
+ {
+ for(i=0;i<test_case.length;i++)
+ {
+ test_case[i].checked=false;
+ }
+ return false;
+ }
+} \ No newline at end of file
diff --git a/yaksh/templates/yaksh/add_question.html b/yaksh/templates/yaksh/add_question.html
index 0d74663..44aca9d 100644
--- a/yaksh/templates/yaksh/add_question.html
+++ b/yaksh/templates/yaksh/add_question.html
@@ -25,11 +25,11 @@
<tr><td>Points:<td><button class="btn-mini" type="button" onClick="increase(frm);">+</button>{{ form.points }}<button class="btn-mini" type="button" onClick="decrease(frm);">-</button>{{ form.points.errors }}
<tr><td><strong>Rendered: </strong><td><p id='my'></p>
<tr><td>Description: <td>{{ form.description}} {{form.description.errors}}
- <tr><td>Snippet: <td>{{ form.snippet }}{{ form.snippet.errors }}</td></tD></td></tr>
+ <!-- <tr><td>Snippet: <td>{{ form.snippet }}{{ form.snippet.errors }}</td></tD></td></tr> -->
<tr><td>Tags: <td>{{ form.tags }}
- <tr><td id='label_option'>Options: <td>{{ form.options }} {{form.options.errors}}
+ <!-- <tr><td id='label_option'>Options: <td>{{ form.options }} {{form.options.errors}} -->
<!-- <tr><td id='label_solution'>Test: <td>{{ form.test }} {{form.test.errors}} -->
- <tr><td id='label_ref_code_path'>Reference Code Path: <td>{{ form.ref_code_path }} {{form.ref_code_path.errors}}
+ <!-- <tr><td id='label_ref_code_path'>Reference Code Path: <td>{{ form.ref_code_path }} {{form.ref_code_path.errors}} -->
<tr><td> test_case_type: <td> {{ form.test_case_type }}{{ form.test_case_type.errors }}
<form method="post" action="">
@@ -41,7 +41,12 @@
{% endif %}
</form>
</table></center>
- <center><button class="btn" type="submit" name="save_question">Save</button>
- <button class="btn" type="button" name="button" onClick='location.replace("{{URL_ROOT}}/exam/manage/questions/");'>Cancel</button> </center>
+ <center>
+ <button class="btn" type="submit" name="save_question">Save</button>
+ <button class="btn" type="button" name="button" onClick='location.replace("{{URL_ROOT}}/exam/manage/questions/");'>Cancel</button>
+ {% if question_id %}
+ <button class="btn" type="button" name="testcase_button" onClick='location.replace("{{URL_ROOT}}/exam/manage/showtestcase/{{ question_id }}/");'>Go To TestCases</button>
+ {% endif %}
+ </center>
</form>
{% endblock %}
diff --git a/yaksh/templates/yaksh/add_testcase.html b/yaksh/templates/yaksh/add_testcase.html
index 298bd50..7e29765 100644
--- a/yaksh/templates/yaksh/add_testcase.html
+++ b/yaksh/templates/yaksh/add_testcase.html
@@ -1,21 +1,39 @@
{% extends "manage.html" %}
-
-{% block subtitle %}Add Question{% endblock %}
+{% block subtitle %}Add Test Case{% endblock %}
{% block css %}
<link rel="stylesheet" href="{{ URL_ROOT }}/static/yaksh/css/question_quiz.css" type="text/css" />
-<link rel="stylesheet" media="all" type="text/css" href="{{ URL_ROOT }}/static/yaksh/css/autotaggit.css" />
{% endblock %}
+{% block manage %}
+<form name=frm id=frm action="" method="post" >
+ {% csrf_token %}
+ <center>
+ <table class=span1>
+ {{ form.as_table }}
+ </table>
+ </center>
+
+ <center><button class="btn primary" type="submit" id="submit" name="testcase">Save</button>
+ <button class="btn primary" type="button" name="button" onClick='location.replace("{{URL_ROOT}}/exam/manage/showtestcase/{{question_id}}");'>Cancel</button> </center>
+</form>
+{% endblock %}
+
+<!-- {% comment %}{% extends "manage.html" %}
+
+{% block subtitle %}Add Testcase{% endblock %}
+
{% block script %}
<script type="text/javascript" src="{{ URL_ROOT }}/static/yaksh/js/jquery-1.4.2.min.js"></script>
-<script src="{{ URL_ROOT }}/static/yaksh/js/add_question.js"></script>
{% endblock %}
{% block onload %} onload='javascript:textareaformat();' {% endblock %}
{% block manage %}
-<form action="" method="post" name=frm>
-<tr><td>Test Case: <td>{{ form.test_case }}{{ form.test_case.errors }}
-</form> \ No newline at end of file
+<form name=testcase_frm id=testcase_frm action="" method="post">
+{{ form.as_table }}
+</form>
+<button class="btn" type="submit" name="save_testcase">Save</button>
+{% endblock %}{% endcomment %}
+ -->
diff --git a/yaksh/templates/yaksh/show_testcase.html b/yaksh/templates/yaksh/show_testcase.html
new file mode 100644
index 0000000..b9cb55f
--- /dev/null
+++ b/yaksh/templates/yaksh/show_testcase.html
@@ -0,0 +1,31 @@
+{% extends "manage.html" %}
+
+{% block title %} Test Case List {% endblock title %}
+
+{% block script %}
+<script src="{{ URL_ROOT }}/static/yaksh/js/show_testcase.js"></script>
+{% endblock %}
+
+{% block subtitle %} Test Case List {% endblock %}
+{% block manage %}
+{% if not test_cases %}
+<center><h5> No Test Cases Available for This Question. </h5></center>
+<button class="btn" type="button" onClick='location.replace("{{URL_ROOT}}/exam/manage/testcase/{{ question_id }}");'>Add New Test Case</button>&nbsp;&nbsp;
+{% endif %}
+
+
+{% if test_cases %}
+<form method="post" action="" name='frm'>
+{% csrf_token %}
+
+{% for test_case in test_cases %}
+<input type=checkbox name='test_case' value={{test_case.id}} />&nbsp;&nbsp;<a href="{{URL_ROOT}}/exam/manage/testcase/{{ question_id }}/{{ test_case.id }}">{{ test_case }}</a><br>
+{% endfor %}
+
+<br><br>
+<button class="btn" type="button" onClick='location.replace("{{URL_ROOT}}/exam/manage/testcase/{{ question_id }}");'>Add New Test Case</button>&nbsp;&nbsp;
+<button class="btn" type="submit" name="delete" value='delete' onClick="return confirm_delete(frm);">Delete Selected</button>
+</form>
+{% endif %}
+
+{% endblock %}
diff --git a/yaksh/views.py b/yaksh/views.py
index c7fdc7f..5f07880 100644
--- a/yaksh/views.py
+++ b/yaksh/views.py
@@ -22,8 +22,9 @@ import json
from yaksh.models import Quiz, Question, QuestionPaper, QuestionSet, Course
from yaksh.models import Profile, Answer, AnswerPaper, User, TestCase
from yaksh.forms import UserRegisterForm, UserLoginForm, QuizForm,\
- QuestionForm, RandomQuestionForm, TestCaseFormSet,\
- QuestionFilterForm, CourseForm, ProfileForm, UploadFileForm
+ QuestionForm, RandomQuestionForm,\
+ QuestionFilterForm, CourseForm, ProfileForm, UploadFileForm,\
+ get_object_form
from yaksh.xmlrpc_clients import code_server
from settings import URL_ROOT
from yaksh.models import AssignmentUpload
@@ -181,8 +182,9 @@ def add_question(request, question_id=None):
return my_redirect("/exam/manage/questions")
return my_render_to_response('yaksh/add_question.html',
- {'form': form},
- # 'formset': test_case_formset},
+ # {'form': form},
+ {'form': form,
+ 'question_id': question_id},
context_instance=ci)
else:
d = Question.objects.get(id=question_id)
@@ -192,56 +194,112 @@ def add_question(request, question_id=None):
question = Question.objects.get(id=question_id)
return my_redirect("/exam/manage/questions")
return my_render_to_response('yaksh/add_question.html',
- {'form': form},
- # 'formset': test_case_formset},
+ # {'form': form},
+ {'form': form,
+ 'question_id': question_id},
context_instance=ci)
else:
return my_render_to_response('yaksh/add_question.html',
- {'form': form},
- # 'formset': test_case_formset},
+ # {'form': form},
+ {'form': form,
+ 'question_id': question_id},
context_instance=ci)
else:
if question_id is None:
form = QuestionForm()
# test_case_formset = TestCaseFormSet(prefix='test', instance=Question())
return my_render_to_response('yaksh/add_question.html',
- {'form': form},
- # 'formset': test_case_formset},
+ # {'form': form},
+ {'form': form,
+ 'question_id': question_id},
context_instance=ci)
else:
d = Question.objects.get(id=question_id)
form = QuestionForm(instance=d)
return my_render_to_response('yaksh/add_question.html',
- {'form': form},
- # 'formset': test_case_formset},
+ # {'form': form},
+ {'form': form,
+ 'question_id': question_id},
context_instance=ci)
@login_required
-def add_testcase(request, question_id=None):
- """To add new test case for a question"""
+def show_testcase(request, question_id=None):
+ """Show all test cases related to Questions"""
+ user = request.user
ci = RequestContext(request)
+ if not user.is_authenticated() or not is_moderator(user):
+ raise Http404('You are not allowed to view this page!')
if not question_id:
raise Http404('No Question Found')
+
question = Question.objects.get(id=question_id)
- initial = {'question': question}
+ test_cases = question.get_test_cases()
+
+ if request.POST.get('delete') == 'delete':
+ data = request.POST.getlist('test_case')
+ for i in data:
+ for t in test_cases:
+ if int(i) == t.id:
+ test_case_deleted = t.delete()
+ test_cases = question.get_test_cases()
+
+ return my_render_to_response('yaksh/show_testcase.html',
+ {'test_cases': test_cases,
+ 'question_id': question_id},
+ context_instance=ci)
+
+
+@login_required
+def add_testcase(request, question_id=None, test_case_id=None):
+ """To add new test case for a question"""
+ user = request.user
+ ci = RequestContext(request)
+ if not user.is_authenticated() or not is_moderator(user):
+ raise Http404('You are not allowed to view this page!')
+ if not question_id:
+ raise Http404('No Question Found')
+
+ question = Question.objects.get(id=question_id)
test_case_type = question.test_case_type
- if test_case_type == "standardtestcase":
- from yaksh.forms import StandardTestCaseForm
- if request.method == "POST":
- form = StandardTestCaseForm(request.POST)
- initial = {'question': question}
- form = StandardTestCaseForm(initial)
+ if test_case_id:
+ instance = question.get_test_case(test_case_id)
+ else:
+ instance = None
+
+ # test_cases = self.testcase_set.all()
+ # for test in test_cases:
+ # test_case_child_instance = test.get_child_instance(test_case_type)
+
+ test_case_form_object = get_object_form(model=test_case_type, exclude_fields=['question'])
+
+ # if test_case_type == "standardtestcase":
+ # from yaksh.forms import StandardTestCaseForm
+ # if request.method == "POST":
+ # form = StandardTestCaseForm(request.POST)
+ # form = StandardTestCaseForm(initial)
if request.method == "POST":
+ form = test_case_form_object(request.POST, instance=instance)
if form.is_valid():
- form.save()
+ form_data = form.save(commit=False)
+ form_data.question = question
+ form_data.save()
+ return my_redirect("/exam/manage/showtestcase/{0}".format(question_id))
+ else:
+ return my_render_to_response('yaksh/add_testcase.html',
+ {'form': form,
+ 'question_id': question_id},
+ context_instance=ci)
+
else:
+ form = test_case_form_object(initial={"question": question}, instance=instance)
return my_render_to_response('yaksh/add_testcase.html',
- {'form': form},
+ {'form': form,
+ 'question_id': question_id},
context_instance=ci)
@login_required