diff options
-rw-r--r-- | yaksh/forms.py | 22 | ||||
-rw-r--r-- | yaksh/models.py | 44 | ||||
-rw-r--r-- | yaksh/static/yaksh/js/show_testcase.js | 24 | ||||
-rw-r--r-- | yaksh/templates/yaksh/add_question.html | 15 | ||||
-rw-r--r-- | yaksh/templates/yaksh/add_testcase.html | 32 | ||||
-rw-r--r-- | yaksh/templates/yaksh/show_testcase.html | 31 | ||||
-rw-r--r-- | yaksh/views.py | 104 |
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> +{% 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}} /> <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> +<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 |