diff options
author | ankitjavalkar | 2015-02-20 18:04:36 +0530 |
---|---|---|
committer | ankitjavalkar | 2015-04-26 19:39:48 +0530 |
commit | 8e2469e937fd4f80ebf2053d6e21c9b670d38ea2 (patch) | |
tree | a2bbecb2f38247faa47440725bf1371c2448682c | |
parent | 591c261ebbbaa0a052ed7b82428a3627ddaa7b1a (diff) | |
download | online_test-8e2469e937fd4f80ebf2053d6e21c9b670d38ea2.tar.gz online_test-8e2469e937fd4f80ebf2053d6e21c9b670d38ea2.tar.bz2 online_test-8e2469e937fd4f80ebf2053d6e21c9b670d38ea2.zip |
Modify form, views and templates to reflect changes made to TestCase model
-rw-r--r-- | testapp/exam/forms.py | 27 | ||||
-rw-r--r-- | testapp/exam/models.py | 16 | ||||
-rw-r--r-- | testapp/exam/templates/exam/add_question.html | 37 | ||||
-rw-r--r-- | testapp/exam/templates/exam/edit_question.html | 34 | ||||
-rw-r--r-- | testapp/exam/views.py | 135 |
5 files changed, 188 insertions, 61 deletions
diff --git a/testapp/exam/forms.py b/testapp/exam/forms.py index 1f12a3b..e3cef40 100644 --- a/testapp/exam/forms.py +++ b/testapp/exam/forms.py @@ -1,5 +1,5 @@ from django import forms -from testapp.exam.models import Profile, Quiz, Question +from exam.models import Profile, Quiz, Question, TestCase from django.contrib.auth import authenticate from django.contrib.auth.models import User @@ -8,6 +8,7 @@ from taggit.forms import TagField from taggit_autocomplete_modified.managers import TaggableManagerAutocomplete from taggit_autocomplete_modified.widgets import TagAutocomplete from taggit_autocomplete_modified import settings +from django.forms.models import inlineformset_factory from string import letters, punctuation, digits import datetime @@ -177,7 +178,7 @@ class QuizForm(forms.Form): new_quiz.save() -class QuestionForm(forms.Form): +class QuestionForm(forms.ModelForm): """Creates a form to add or edit a Question. It has the related fields and functions required.""" @@ -186,8 +187,8 @@ class QuestionForm(forms.Form): description = forms.CharField(widget=forms.Textarea\ (attrs={'cols': 40, 'rows': 1})) points = forms.FloatField() - test = forms.CharField(widget=forms.Textarea\ - (attrs={'cols': 40, 'rows': 1})) + # test = forms.CharField(widget=forms.Textarea\ + # (attrs={'cols': 40, 'rows': 1}), required=False) options = forms.CharField(widget=forms.Textarea\ (attrs={'cols': 40, 'rows': 1}), required=False) language = forms.CharField(max_length=20, widget=forms.Select\ @@ -199,11 +200,11 @@ class QuestionForm(forms.Form): snippet = forms.CharField(widget=forms.Textarea\ (attrs={'cols': 40, 'rows': 1}), required=False) - def save(self): + def save(self, commit=True): summary = self.cleaned_data["summary"] description = self.cleaned_data["description"] points = self.cleaned_data['points'] - test = self.cleaned_data["test"] + # test = self.cleaned_data["test"] options = self.cleaned_data['options'] language = self.cleaned_data['language'] type = self.cleaned_data["type"] @@ -214,13 +215,20 @@ class QuestionForm(forms.Form): new_question.summary = summary new_question.description = description new_question.points = points - new_question.test = test + # new_question.test = test new_question.options = options new_question.language = language new_question.type = type new_question.active = active new_question.snippet = snippet - new_question.save() + new_question = super(QuestionForm, self).save(commit=False) + if commit: + new_question.save() + + return new_question + + class Meta: + model = Question class RandomQuestionForm(forms.Form): @@ -229,3 +237,6 @@ class RandomQuestionForm(forms.Form): marks = forms.CharField(max_length=8, widget=forms.Select\ (choices=(('select', 'Select Marks'),))) shuffle_questions = forms.BooleanField(required=False) + +TestCaseFormSet = inlineformset_factory(Question, TestCase,\ + can_order=False, can_delete=False, extra=1) diff --git a/testapp/exam/models.py b/testapp/exam/models.py index 4b8f737..ea79ad2 100644 --- a/testapp/exam/models.py +++ b/testapp/exam/models.py @@ -59,8 +59,8 @@ class Question(models.Model): # Number of points for the question. points = models.FloatField(default=1.0) - # Test cases for the question in the form of code that is run. - test = models.TextField(blank=True) + # # Test cases for the question in the form of code that is run. + # test = models.TextField(blank=True) # Any multiple choice options. Place one option per line. options = models.TextField(blank=True) @@ -429,19 +429,19 @@ class AssignmentUpload(models.Model): ################################################################################ class TestCase(models.Model): - question = models.ForeignKey(Question) + question = models.ForeignKey(Question, blank=True, null = True) # Test case function name - func_name = models.CharField(max_length=200) + func_name = models.CharField(blank=True, null = True, max_length=200) # Test case Keyword arguments in dict form - kw_args = models.TextField(blank=True) + kw_args = models.TextField(blank=True, null = True) # Test case Positional arguments in list form - pos_args = models.TextField(blank=True) + pos_args = models.TextField(blank=True, null = True) # Test case Expected answer in list form - expected_answer = models.TextField(blank=True) + expected_answer = models.TextField(blank=True, null = True) # Test case path to system test code applicable for CPP, C, Java and Scilab - ref_code_path = models.TextField(blank=True) + ref_code_path = models.TextField(blank=True, null = True) diff --git a/testapp/exam/templates/exam/add_question.html b/testapp/exam/templates/exam/add_question.html index b6ce908..d989b81 100644 --- a/testapp/exam/templates/exam/add_question.html +++ b/testapp/exam/templates/exam/add_question.html @@ -27,17 +27,38 @@ <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>Test: <td>{{ form.test }}{{form.test.errors}} - <tr><td>Test Keyword Arguments: <td>{{ form.test_keyword_args }}{{form.test.errors}} <!-- --> - <tr><td>Test Positional Arguments: <td>{{ form.test_pos_args }}{{form.test.errors}} <!-- --> - <tr><td>Test Expected Answer: <td>{{ form.test_expected_answer }}{{form.test.errors}} <!-- --> + <!-- <tr><td>Test: <td>{{ form.test }}{{form.test.errors}} --> <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}} + <!-- start --> + <form method="post" action=""> + {% if formset%} + {{ formset.management_form }} + {% for form in formset %} + {{ form }} + {% endfor %} + {% endif %} + </form> +<!-- <form method="post" action=""> + <center><table class=span1> + {{ formset.management_form }} + {% for form in formset %} + {{ form.id }} + <tr><td>Question <td>{{ form.question }} + <tr><td>Function Name <td>{{ form.func_name }} + <tr><td>Keyword argument <td>{{ form.kw_args }} + <tr><td>Positional Argument <td>{{ form.pos_args }} + <tr><td>Expected Answer <td>{{ form.expected_answer }} + <tr><td>Code Path <td>{{ form.ref_code_path }} + {% endfor %} + </form> --> + <!-- end --> </table></center> - <center><button class="btn" type="submit" name="savequestion">Save</button> + <center><button class="btn" type="submit" name="add_test">Add Test Case</button> <!-- --> + <button class="btn" type="submit" name="delete_test">Remove Test Case</button> <!-- --> + </center><br> + <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> </form> {% endblock %} diff --git a/testapp/exam/templates/exam/edit_question.html b/testapp/exam/templates/exam/edit_question.html index b28cc3e..1c34dee 100644 --- a/testapp/exam/templates/exam/edit_question.html +++ b/testapp/exam/templates/exam/edit_question.html @@ -21,7 +21,7 @@ <table> - {% for form in forms %} +<!-- {% for form in forms %} <tr><td height=10><a id='a{{forloop.counter}}' onClick="data('contentDiv{{forloop.counter}}','myContent{{forloop.counter}}','a{{forloop.counter}}','{{form.summary.value}}');" style='cursor:pointer;'>{{form.summary.value}}</a> @@ -43,7 +43,39 @@ </div> </div> {% endfor %} +</table></center> --> + + {% for question, test in data_list %} + + <tr><td height=10><a id='a{{forloop.counter}}' onClick="data('contentDiv{{forloop.counter}}','myContent{{forloop.counter}}','a{{forloop.counter}}','{{question.summary.value}}');" style='cursor:pointer;'>{{question.summary.value}}</a> + + <div id="contentDiv{{forloop.counter}}" style="display:none;"> + <div id="myContent{{forloop.counter}}" style="display: none;"> + + <center><table class=span1> + <tr><td><b>Summary:</b> <td>{{ question.summary }}{{ question.summary.errors }} + <tr><td><b> Language: </b><td> {{question.language}}{{question.language.errors}} + <tr><td><b> Active: </b><td> {{ question.active }}{{question.active.errors}} Type: {{ question.type }}{{question.type.errors}} + <tr><td><b>Points:<td><button class="btn-mini" name={{forloop.counter}} type="button" onClick="increase(frm,{{forloop.counter}});">+</button>{{ question.points }}<button class="btn-mini" type="button" onClick="decrease(frm,{{forloop.counter}});">-</button>{{ question.points.errors }} + <tr><td><strong>Rendered: </strong><td><p id='my{{forloop.counter}}'></p> + <tr><td><b>Description: <td>{{ question.description }} + {{question.description.errors}} <tr><td><b>Test: <td> + {{ question.test }}{{question.test.errors}} + <tr><td><b>Snippet: <td>{{ question.snippet }}{{ question.snippet.errors }} + </td></b></td></tr> + <tr><td><b>Tags: </b><td>{{ question.tags }} + <tr><td id='label_option{{forloop.counter}}'><b>Options:<td>{{ question.options }} + {{question.options.errors}} {{question.options.helptext}} + </table></center> + <center><table class=span1> + {{ test }} + </table></center> + </div> + </div> + {% endfor %} </table></center> + + {% for i in data %} <input type=hidden name='questions' value="{{ i }}" /> {% endfor %} diff --git a/testapp/exam/views.py b/testapp/exam/views.py index be0d292..3d22d55 100644 --- a/testapp/exam/views.py +++ b/testapp/exam/views.py @@ -18,8 +18,8 @@ from itertools import chain from testapp.exam.models import Quiz, Question, QuestionPaper, QuestionSet from testapp.exam.models import Profile, Answer, AnswerPaper, User, TestCase from testapp.exam.forms import UserRegisterForm, UserLoginForm, QuizForm,\ - QuestionForm, RandomQuestionForm -from testapp.exam.xmlrpc_clients import code_server + QuestionForm, RandomQuestionForm, TestCaseFormSet +from exam.xmlrpc_clients import code_server from settings import URL_ROOT from testapp.exam.models import AssignmentUpload @@ -281,7 +281,7 @@ def edit_quiz(request): def edit_question(request): - """Edit the list of questions seleted by the user for editing.""" + """Edit the list of questions selected by the user for editing.""" user = request.user if not user.is_authenticated() or not is_moderator(user): raise Http404('You are not allowed to view this page!') @@ -290,7 +290,6 @@ def edit_question(request): summary = request.POST.getlist('summary') description = request.POST.getlist('description') points = request.POST.getlist('points') - test = request.POST.getlist('test') options = request.POST.getlist('options') type = request.POST.getlist('type') active = request.POST.getlist('active') @@ -298,10 +297,15 @@ def edit_question(request): snippet = request.POST.getlist('snippet') for j, question_id in enumerate(question_list): question = Question.objects.get(id=question_id) + test_case_formset = TestCaseFormSet(request.POST, prefix='test', instance=question) + if test_case_formset.is_valid(): + test_case_instance = test_case_formset.save(commit=False) + for i in test_case_instance: + i.save() + question.summary = summary[j] question.description = description[j] question.points = points[j] - question.test = test[j] question.options = options[j] question.active = active[j] question.language = language[j] @@ -314,6 +318,16 @@ def edit_question(request): def add_question(request, question_id=None): """To add a new question in the database. Create a new question and store it.""" + + def add_or_delete_test_form(post_request, instance): + request_copy = post_request.copy() + if 'add_test' in post_request: + request_copy['test-TOTAL_FORMS'] = int(request_copy['test-TOTAL_FORMS']) + 1 + elif 'delete_test' in post_request: + request_copy['test-TOTAL_FORMS'] = int(request_copy['test-TOTAL_FORMS']) - 1 + test_case_formset = TestCaseFormSet(request_copy, prefix='test', instance=instance) + return test_case_formset + user = request.user ci = RequestContext(request) if not user.is_authenticated() or not is_moderator(user): @@ -321,44 +335,84 @@ def add_question(request, question_id=None): if request.method == "POST": form = QuestionForm(request.POST) if form.is_valid(): - data = form.cleaned_data if question_id is None: - form.save() - question = Question.objects.order_by("-id")[0] - tags = form['tags'].data.split(',') - for i in range(0, len(tags)-1): - tag = tags[i].strip() - question.tags.add(tag) - return my_redirect("/exam/manage/questions") + test_case_formset = add_or_delete_test_form(request.POST, form.save(commit=False)) + if 'save_question' in request.POST: + qtn = form.save(commit=False) + test_case_formset = TestCaseFormSet(request.POST, prefix='test', instance=qtn) + form.save() + question = Question.objects.order_by("-id")[0] + tags = form['tags'].data.split(',') + for i in range(0, len(tags)-1): + tag = tags[i].strip() + question.tags.add(tag) + if test_case_formset.is_valid(): + test_case_formset.save() + else: + return my_render_to_response('exam/add_question.html', + {'form': form, + 'formset': test_case_formset}, + context_instance=ci) + + return my_redirect("/exam/manage/questions") + + return my_render_to_response('exam/add_question.html', + {'form': form, + 'formset': test_case_formset}, + context_instance=ci) + else: d = Question.objects.get(id=question_id) - d.summary = form['summary'].data - d.description = form['description'].data - d.points = form['points'].data - d.test = form['test'].data - d.options = form['options'].data - d.type = form['type'].data - d.active = form['active'].data - d.language = form['language'].data - d.snippet = form['snippet'].data - d.save() - question = Question.objects.get(id=question_id) - for tag in question.tags.all(): - question.tags.remove(tag) - tags = form['tags'].data.split(',') - for i in range(0, len(tags)-1): - tag = tags[i].strip() - question.tags.add(tag) - return my_redirect("/exam/manage/questions") + test_case_formset = add_or_delete_test_form(request.POST, d) + if 'save_question' in request.POST: + d.summary = form['summary'].data + d.description = form['description'].data + d.points = form['points'].data + d.options = form['options'].data + d.type = form['type'].data + d.active = form['active'].data + d.language = form['language'].data + d.snippet = form['snippet'].data + d.save() + question = Question.objects.get(id=question_id) + for tag in question.tags.all(): + question.tags.remove(tag) + tags = form['tags'].data.split(',') + for i in range(0, len(tags)-1): + tag = tags[i].strip() + question.tags.add(tag) + + test_case_formset = TestCaseFormSet(request.POST, prefix='test', instance=question) + if test_case_formset.is_valid(): + test_case_instance = test_case_formset.save(commit=False) + for i in test_case_instance: + i.save() + else: + return my_render_to_response('exam/add_question.html', + {'form': form, + 'formset': test_case_formset}, + context_instance=ci) + + + return my_redirect("/exam/manage/questions") + return my_render_to_response('exam/add_question.html', + {'form': form, + 'formset': test_case_formset}, + context_instance=ci) + else: return my_render_to_response('exam/add_question.html', {'form': form}, context_instance=ci) else: + form = QuestionForm() + test_case_formset = TestCaseFormSet(prefix='test', instance=Question()) if question_id is None: form = QuestionForm() + test_case_formset = TestCaseFormSet(prefix='test', instance=Question()) return my_render_to_response('exam/add_question.html', - {'form': form}, + {'form': form, + 'formset': test_case_formset}, context_instance=ci) else: d = Question.objects.get(id=question_id) @@ -366,7 +420,6 @@ def add_question(request, question_id=None): form.initial['summary'] = d.summary form.initial['description'] = d.description form.initial['points'] = d.points - form.initial['test'] = d.test form.initial['options'] = d.options form.initial['type'] = d.type form.initial['active'] = d.active @@ -380,8 +433,13 @@ def add_question(request, question_id=None): if (initial_tags == ","): initial_tags = "" form.initial['tags'] = initial_tags + + test_case_formset = TestCaseFormSet(prefix='test', + instance=d) + return my_render_to_response('exam/add_question.html', - {'form': form}, + {'form': form, + 'formset': test_case_formset}, context_instance=ci) @@ -1172,13 +1230,13 @@ def show_all_questions(request): data = request.POST.getlist('question') forms = [] + formsets = [] for j in data: d = Question.objects.get(id=j) form = QuestionForm() form.initial['summary'] = d.summary form.initial['description'] = d.description form.initial['points'] = d.points - form.initial['test'] = d.test form.initial['options'] = d.options form.initial['type'] = d.type form.initial['active'] = d.active @@ -1193,8 +1251,13 @@ def show_all_questions(request): initial_tags = "" form.initial['tags'] = initial_tags forms.append(form) + test_case_formset = TestCaseFormSet(prefix='test', instance=d) + formsets.append(test_case_formset) + data_list = zip(forms, formsets) + return my_render_to_response('exam/edit_question.html', - {'forms': forms, 'data': data}, + {'data': data, + 'data_list': data_list}, context_instance=ci) else: questions = Question.objects.all() |