]> git.parisson.com Git - django_quiz.git/commitdiff
finalised essay question type, added it to admin and readme, adjusted
authorTom Walker <tomwalker0472@gmail.com>
Sun, 27 Jul 2014 13:15:58 +0000 (14:15 +0100)
committerTom Walker <tomwalker0472@gmail.com>
Sun, 27 Jul 2014 13:15:58 +0000 (14:15 +0100)
sitting detail view to allow a marker to decide whether a question is
correct, added supporting methods to the sitting model

README.md
essay/admin.py
essay/models.py
essay/views.py
quiz/forms.py
quiz/models.py
quiz/templates/quiz/sitting_detail.html
quiz/tests.py
quiz/views.py

index 4ebb78d82864605f653920f191b23593f06be1a7..45e131b0fd9faec8a1f98700c4bca4da7fe9fb83 100644 (file)
--- a/README.md
+++ b/README.md
@@ -26,8 +26,10 @@ Features of each quiz:
 * Pass marks can be set
 * Multiple choice question type
 * True/False question type
+* Essay question type
 * Custom message displayed for those that pass or fail a quiz
 * Custom permission (view_sittings) added, allowing users with that permission to view quiz results from users
+* A marking page which lists completed quizzes, can be filtered by quiz or user, and is used to mark essay questions
 
 
 
index 8c38f3f3dad51e4585f3984282c2a4bec5349c1e..d3c1eff310f0a48487853c79b06f38107c1d10e5 100644 (file)
@@ -1,3 +1 @@
-from django.contrib import admin
-
-# Register your models here.
+# from django.contrib import admin
index 96a6b43f61e0565dc636273bdb57da5e92c1f80b..9f0c5d1830890368a7c75a8ae40a339327d826b0 100644 (file)
@@ -15,5 +15,8 @@ class Essay_Question(Question):
     def answer_choice_to_string(self, guess):
         return str(guess)
 
+    def __unicode__(self):
+        return unicode(self.content)
+
     class Meta:
         verbose_name = "Essay style question"
index 91ea44a218fbd2f408430959283f0419c921093e..497e34224c65e7884dffd9078ff789c0959971d4 100644 (file)
@@ -1,3 +1 @@
-from django.shortcuts import render
-
-# Create your views here.
+#from django.shortcuts import render
index bb74388fbc6e972a5330f1ada1386b11d8483271..c7ddf699c4c6e7d18ba1756e604a26432226cc1e 100644 (file)
@@ -13,4 +13,5 @@ class QuestionForm(forms.Form):
 class EssayForm(forms.Form):
     def __init__(self, question, *args, **kwargs):
         super(EssayForm, self).__init__(*args, **kwargs)
-        self.fields["answers"] = forms.CharField(widget=Textarea)
+        self.fields["answers"] = forms.CharField(
+            widget=Textarea(attrs={'style': 'width:100%'}))
index 97d64f0c31cc09e2720b46ea768638eb7641ac78..60ed009c46006e7c105f2aa4c419c3f06b500797 100644 (file)
@@ -358,7 +358,7 @@ class Sitting(models.Model):
             self.save()
 
     def add_to_score(self, points):
-        self.current_score = self.get_current_score + int(points)
+        self.current_score += int(points)
         self.save()
 
     @property
@@ -391,9 +391,11 @@ class Sitting(models.Model):
         Adds uid of incorrect question to the list.
         The question object must be passed in.
         """
-        if isinstance(question, Question) is False:
-            return False
-        self.incorrect_questions += str(question.id) + ","
+        if len(self.incorrect_questions) > 0:
+            self.incorrect_questions += ','
+        self.incorrect_questions +=  str(question.id) + ","
+        if self.complete:
+            self.add_to_score(-1)
         self.save()
 
     @property
@@ -404,6 +406,13 @@ class Sitting(models.Model):
         """
         return [int(q) for q in self.incorrect_questions.split(',') if q]
 
+    def remove_incorrect_question(self, question):
+        current = self.get_incorrect_questions
+        current.remove(question.id)
+        self.incorrect_questions = ','.join(map(str, current))
+        self.add_to_score(1)
+        self.save()
+
     @property
     def check_if_passed(self):
         if self.get_percent_correct >= self.quiz.pass_mark:
@@ -429,7 +438,6 @@ class Sitting(models.Model):
         user_answers = json.loads(self.user_answers)
         for question in self.quiz.question_set.all().select_subclasses():
             output[question] = user_answers[unicode(question.id)]
-
         return output
 
 
index a685b9a525b676983affc62fcecbde66c3dc04b4..254dfb5c64ca7115108607556a3a77de082774a7 100644 (file)
@@ -18,9 +18,10 @@ Result of {{ sitting.quiz.title }} for {{ sitting.user }}
          <th>Question</th>
          <th>User answer</th>
          <th></th>
+         <th></th>
        </tr>
   </thead>
-n
+
   <tbody>
 {% for question, user_name in questions.items %}
 
@@ -31,9 +32,15 @@ n
                {% if question.id in incorrect %}
                  <p>incorrect</p>
                {% else %}
-                 <p>correct</p>
+                 <p>Correct</p>
                {% endif %}
          </td>
+         <td>
+               <form action="" method="get">
+                 <input type=hidden name="id" value="{{ question.id }}">
+                 <button type="submit">Toggle whether correct</button>
+               </form>
+         </td>
        </tr>
 
 {% endfor %}
index 0e4a2f765cf043037caab19ae04e53b604edc0e5..85b7340afd0c72da07ed222d551d33d5ec65c295 100644 (file)
@@ -13,6 +13,7 @@ from .models import Category, Quiz, Progress, Sitting
 from .views import anon_session_score
 from multichoice.models import MCQuestion, Answer
 from true_false.models import TF_Question
+from essay.models import Essay_Question
 
 
 class TestCategory(TestCase):
@@ -246,14 +247,14 @@ class TestSitting(TestCase):
         self.sitting.add_incorrect_question(question3)
         self.assertIn(3, self.sitting.get_incorrect_questions)
 
-        f_test = self.sitting.add_incorrect_question(self.quiz1)
-        self.assertEqual(f_test, False)
-        self.assertNotIn('test', self.sitting.get_incorrect_questions)
-
         self.assertEqual(self.sitting.complete, False)
         self.sitting.mark_quiz_complete()
         self.assertEqual(self.sitting.complete, True)
 
+        self.assertEqual(self.sitting.current_score, 0)
+        self.sitting.add_incorrect_question(self.question2)
+        self.assertEqual(self.sitting.current_score, -1)
+
     def test_add_user_answer(self):
         guess = '123'
         self.sitting.add_user_answer(self.question1, guess)
@@ -268,6 +269,13 @@ class TestSitting(TestCase):
         self.assertEqual('123', user_answers[self.question1])
         self.assertEqual('456', user_answers[self.question2])
 
+    def test_remove_incorrect_answer(self):
+        self.sitting.add_incorrect_question(self.question1)
+        self.sitting.add_incorrect_question(self.question2)
+        self.sitting.remove_incorrect_question(self.question1)
+        self.assertEqual(self.sitting.incorrect_questions, '2')
+        self.assertEqual(self.sitting.current_score, 1)
+
 
 '''
 Tests relating to views
@@ -400,7 +408,6 @@ class TestQuestionMarking(TestCase):
         sitting2.save()
 
         sitting1.add_user_answer(self.question1, '123')
-        # sitting1.add_user_answer(self.question2, '456')
 
     def test_paper_marking_list_view(self):
         response = self.client.get('/marking/')
@@ -457,6 +464,28 @@ class TestQuestionMarking(TestCase):
         self.assertContains(response, 'squawk')
         self.assertContains(response, 'incorrect')
 
+    def test_paper_marking_detail_toggle_correct(self):
+        question2 = Essay_Question.objects.create(id=3, content='scribble')
+        question2.quiz.add(self.quiz1)
+
+        sitting3 = Sitting.objects.new_sitting(self.student, self.quiz1)
+        sitting3.complete = True
+        sitting3.incorrect_questions = '1,2,3'
+        sitting3.add_user_answer(self.question1, '123')
+        sitting3.add_user_answer(question2, 'Blah blah blah')
+        sitting3.save()
+
+        self.client.login(username='yoda', password='use_d@_force')
+        response = self.client.get('/marking/3/')
+        self.assertContains(response, 'button')
+        self.assertNotContains(response, 'Correct')
+
+        response = self.client.get('/marking/3/', {'id': 3})
+        self.assertContains(response, 'Correct')
+
+        response = self.client.get('/marking/3/', {'id': 3})
+        self.assertNotContains(response, 'Correct')
+
 
 class TestQuestionViewsAnon(TestCase):
     urls = 'quiz.urls'
index 29b25a1887001f1771ba27bbb39c153141088818..9889fb720756f70b5d176bcd29e70e16328004f4 100644 (file)
@@ -95,9 +95,18 @@ class QuizMarkingList(QuizMarkerMixin, ListView):
 class QuizMarkingDetail(QuizMarkerMixin, DetailView):
     model = Sitting
 
-    def dispatch(self, request, *args, **kwargs):
-        return super(QuizMarkingDetail, self)\
-            .dispatch(request, *args, **kwargs)
+    def get_object(self, queryset=None):
+        sitting = super(QuizMarkingDetail, self).get_object()
+
+        q_to_toggle = self.request.GET.get('id')
+        if q_to_toggle:
+            q = Question.objects.get_subclass(id=int(q_to_toggle))
+            if int(q_to_toggle) in sitting.get_incorrect_questions:
+                sitting.remove_incorrect_question(q)
+            else:
+                sitting.add_incorrect_question(q)
+
+        return sitting
 
     def get_context_data(self, **kwargs):
         context = super(QuizMarkingDetail, self).get_context_data(**kwargs)