objects = SittingManager()
- def get_next_question(self):
+ def get_first_question(self):
"""
Returns integer of the next question ID.
If no question is found, returns False
<p class="muted"><small>The previous question:</small></p>
<p>{{ previous.previous_question }}</p>
- {% ifequal previous.previous_outcome 'correct' %}
+ {% if previous.previous_outcome %}
<div class="alert alert-success">
{% else %}
<div class="alert alert-warning">
- {% endifequal %}
+ {% endif %}
<p><small>Your answer was </small><strong>{{ previous.previous_outcome }}</strong></p>
</div>
--- /dev/null
+{% extends 'base.html' %}
+{% block title %}
+{{ quiz.title }}
+{% endblock %}
+
+{% block content %}
+<h2>{{ quiz.title }}</h2>
+<h3>Category: {{ quiz.category }}</h3>
+{% if quiz.single_attempt %}
+ <h4>You will only get one attempt at this quiz.</h4>
+{% endif %}
+<p>{{ quiz.description }}</p>
+<p><a href="{% url 'quiz.views.quiz_take' quiz_name=quiz.url %}">Start quiz</a></p>
+{% endblock %}
self.sitting = Sitting.objects.new_sitting(self.user, self.quiz1)
def test_get_next_remove_first(self):
- self.assertEqual(self.sitting.get_next_question(), 1)
+ self.assertEqual(self.sitting.get_first_question(), 1)
self.sitting.remove_first_question()
- self.assertEqual(self.sitting.get_next_question(), 2)
+ self.assertEqual(self.sitting.get_first_question(), 2)
self.sitting.remove_first_question()
- self.assertEqual(self.sitting.get_next_question(), False)
+ self.assertEqual(self.sitting.get_first_question(), False)
self.sitting.remove_first_question()
- self.assertEqual(self.sitting.get_next_question(), False)
+ self.assertEqual(self.sitting.get_first_question(), False)
def test_scoring(self):
self.assertEqual(self.sitting.get_current_score(), 0)
title='test quiz 1',
description='d1',
url='tq1',
- category=self.c1)
+ category=self.c1,
+ single_attempt=True)
self.quiz2 = Quiz.objects.create(id=2,
title='test quiz 2',
description='d2',
self.assertContains(response, 'var difference = 2 - 1;')
self.assertContains(response, 'var correct = 1;')
+ def test_quiz_start_page(self):
+ response = self.client.get('/q/tq1/')
+
+ self.assertContains(response, 'd1')
+ self.assertContains(response, 'attempt')
+ self.assertContains(response, 'href="/q/tq1/take/"')
+ self.assertTemplateUsed(response, 'quiz/quiz_detail.html')
+
class TestQuestionViewsAnon(TestCase):
correct=True,)
def test_quiz_take_anon_view_only(self):
- found = resolve('/q/tq1/')
+ found = resolve('/q/tq1/take/')
self.assertEqual(found.func, quiz_take)
self.assertEqual(found.kwargs, {'quiz_name': 'tq1'})
- self.assertEqual(found.url_name, 'quiz_start_page')
+ self.assertEqual(found.url_name, 'quiz_question')
- response = self.client.get('/q/tq1/')
+ response = self.client.get('/q/tq1/take/')
self.assertContains(response, 'squawk', status_code=200)
self.assertEqual(self.client.session.get_expiry_age(), 259200)
session.set_expiry(1) # session is set when user first starts a
session.save() # quiz, not on subsequent visits
- self.client.get('/q/tq1/')
+ self.client.get('/q/tq1/take/')
self.assertEqual(self.client.session.get_expiry_age(), 1)
self.assertEqual(self.client.session['1_q_list'], [1, 2])
self.assertEqual(self.client.session['1_score'], 0)
def test_quiz_take_anon_submit(self):
# show first question
- response = self.client.get('/q/tq1/')
+ response = self.client.get('/q/tq1/take/')
self.assertNotContains(response, 'previous question')
first_question = response.context['question']
# submit first answer
- response = self.client.get('/q/tq1/',
+ response = self.client.get('/q/tq1/take/',
{'guess': '123',
'question_id':
self.client.session['1_q_list'][0]})
second_question = response.context['question']
# submit second and final answer of quiz, show final result page
- response = self.client.get('/q/tq1/',
+ response = self.client.get('/q/tq1/take/',
{'guess': '456',
'question_id':
self.client.session['1_q_list'][0]})
self.assertTemplateUsed('result.html')
# quiz restarts
- response = self.client.get('/q/tq1/')
+ response = self.client.get('/q/tq1/take/')
self.assertNotContains(response, 'previous question')
# session score continues to increase
- response = self.client.get('/q/tq1/',
+ response = self.client.get('/q/tq1/take/',
{'guess': '123',
'question_id':
self.client.session['1_q_list'][0]})
def test_anon_cannot_sit_single_attempt(self):
self.quiz1.single_attempt = True
self.quiz1.save()
- response = self.client.get('/q/tq1/')
+ response = self.client.get('/q/tq1/take/')
self.assertContains(response, 'accessible')
self.assertTemplateUsed('single_complete.html')
self.assertEqual(sittings_before, 0)
self.client.login(username='jacob', password='top_secret')
- response = self.client.get('/q/tq1/')
+ response = self.client.get('/q/tq1/take/')
sitting = Sitting.objects.get(quiz=self.quiz1)
sittings_after = Sitting.objects.count()
self.assertEqual(response.context['show_advert'], False)
self.assertTemplateUsed('question.html')
- response = self.client.get('/q/tq1/')
+ response = self.client.get('/q/tq1/take/')
sittings_after = Sitting.objects.count()
self.assertEqual(sittings_after, 1) # new sitting not made
self.assertEqual(Sitting.objects.count(), 2)
- response = self.client.get('/q/tq1/')
+ response = self.client.get('/q/tq1/take/')
sitting = Sitting.objects.filter(quiz=self.quiz1)[0]
self.assertEqual(sitting.question_list, '1,2,')
def test_quiz_take_user_submit(self):
self.client.login(username='jacob', password='top_secret')
- response = self.client.get('/q/tq1/')
+ response = self.client.get('/q/tq1/take/')
progress_count = Progress.objects.count()
self.assertNotContains(response, 'previous question')
self.assertEqual(progress_count, 0)
next_question = Sitting.objects.get(quiz=self.quiz1)\
- .get_next_question()
+ .get_first_question()
- response = self.client.get('/q/tq1/',
+ response = self.client.get('/q/tq1/take/',
{'guess': '123',
'question_id':
next_question})
self.question2.content)
self.assertTemplateUsed('question.html')
- response = self.client.get('/q/tq1/',
+ response = self.client.get('/q/tq1/take/',
{'guess': '456',
'question_id': 2})
def test_quiz_take_user_answer_end(self):
self.client.login(username='jacob', password='top_secret')
- response = self.client.get('/q/tq2/',
+ response = self.client.get('/q/tq2/take/',
{'guess': '123',
'question_id': 1})
self.assertNotContains(response, 'previous question')
self.assertEqual(response.context['previous'], {})
- response = self.client.get('/q/tq2/',
+ response = self.client.get('/q/tq2/take/',
{'guess': 'T',
'question_id': 3})
self.quiz2.single_attempt = True
self.quiz2.save()
self.client.login(username='jacob', password='top_secret')
- response = self.client.get('/q/tq2/',
+ response = self.client.get('/q/tq2/take/',
{'guess': '123',
'question_id': 1})
- response = self.client.get('/q/tq2/',
+ response = self.client.get('/q/tq2/take/',
{'guess': 'T',
'question_id': 3})
# quiz complete, trying it again
- response = self.client.get('/q/tq2/')
+ response = self.client.get('/q/tq2/take/')
self.assertContains(response, 'only one sitting is permitted.')
self.assertTemplateUsed('single_complete.html')
from django.conf.urls import patterns, url
from .views import QuizListView, CategoriesListView,\
- ViewQuizListByCategory, QuizUserProgressView
+ ViewQuizListByCategory, QuizUserProgressView, QuizDetailView
urlpatterns = patterns('quiz.views',
- # quiz base url
+
url(regex=r'^$',
view=QuizListView.as_view(),
name='quiz_index'),
view=CategoriesListView.as_view(),
name='quiz_category_list_all'),
- # quiz category: list quizzes
url(regex=r'^category/(?P<category_name>[\w.-]+)/$',
view=ViewQuizListByCategory.as_view(),
name='quiz_category_list_matching'),
- # progress
url(regex=r'^progress/$',
view=QuizUserProgressView.as_view(),
name='quiz_progress'),
# passes variable 'quiz_name' to quiz_take view
- url(regex=r'^(?P<quiz_name>[\w-]+)/$',
- view='quiz_take',
+ url(regex=r'^(?P<slug>[\w-]+)/$',
+ view=QuizDetailView.as_view(),
name='quiz_start_page'),
url(regex=r'^(?P<quiz_name>[\w-]+)/take/$',
from django.shortcuts import get_object_or_404, render, render_to_response
from django.template import RequestContext
from django.utils.decorators import method_decorator
-from django.views.generic import ListView, TemplateView
+from django.views.generic import DetailView, ListView, TemplateView
from .models import Quiz, Category, Progress, Sitting, Question
model = Quiz
+class QuizDetailView(DetailView):
+ model = Quiz
+ slug_field = 'url'
+
+
class CategoriesListView(ListView):
model = Category
if request.user.is_authenticated() is True:
- if quiz.single_attempt is True:
- try:
- Sitting.objects.get(user=request.user,
- quiz=quiz,
- complete=True)
- except Sitting.DoesNotExist:
- pass
- except Sitting.MultipleObjectsReturned:
- return render(request, 'single_complete.html')
- else:
- return render(request, 'single_complete.html')
+ if quiz.single_attempt is True and\
+ Sitting.objects.filter(user=request.user,
+ quiz=quiz,
+ complete=True)\
+ .count() > 0:
+ return render(request, 'single_complete.html')
try:
- previous_sitting = Sitting.objects.get(user=request.user,
- quiz=quiz,
- complete=False,)
+ sitting = Sitting.objects.get(user=request.user,
+ quiz=quiz,
+ complete=False)
except Sitting.DoesNotExist:
- return user_new_quiz_session(request, quiz)
+ sitting = Sitting.objects.new_sitting(request.user, quiz)
- except Sitting.MultipleObjectsReturned:
- previous_sitting = Sitting.objects.filter(user=request.user,
- quiz=quiz,
- complete=False,
- )[0]
+ if 'page_count' not in request.session:
+ # session page count
+ request.session['page_count'] = 0
- return user_load_next_question(request, previous_sitting, quiz)
+ except Sitting.MultipleObjectsReturned:
+ sitting = Sitting.objects.filter(user=request.user,
+ quiz=quiz,
+ complete=False)[0]
- else:
- return user_load_next_question(request, previous_sitting, quiz)
+ finally:
+ return user_load_next_question(request, sitting, quiz)
else: # anon user
if quiz.single_attempt is True:
return load_anon_next_question(request, quiz)
-def user_new_quiz_session(request, quiz):
- sitting = Sitting.objects.new_sitting(request.user, quiz)
-
- if 'page_count' not in request.session:
- # session page count
- request.session['page_count'] = 0
-
- return user_load_next_question(request, sitting, quiz)
-
-
def load_anon_next_question(request, quiz):
question_list = request.session[str(quiz.id) + "_q_list"]
previous = {}
def user_load_next_question(request, sitting, quiz):
previous = {}
+ if 'guess' in request.GET:
+ progress, created = Progress.objects.get_or_create(user=request.user)
+ guess = request.GET['guess']
+ previous_question_id = sitting.get_first_question()
+ question = Question.objects.get_subclass(id=previous_question_id)
+ is_correct = question.check_if_correct(guess)
+
+ if is_correct is True:
+ sitting.add_to_score(1)
+ progress.update_score(question.category, 1, 1)
+
+ else:
+ sitting.add_incorrect_question(question)
+ progress.update_score(question.category, 0, 1)
+
+ if quiz.answers_at_end is not True:
+ previous = {'previous_answer': guess,
+ 'previous_outcome': is_correct,
+ 'previous_question': question}
- if 'guess' in request.GET and request.GET['guess']:
- previous = question_check_user(request, quiz, sitting)
sitting.remove_first_question()
request.session['page_count'] = request.session['page_count'] + 1
- question_ID = sitting.get_next_question()
+ question_ID = sitting.get_first_question()
if question_ID is False:
# no questions left
return {}
-def question_check_user(request, quiz, sitting):
- guess = request.GET['guess']
- question_id = request.GET['question_id']
- question = Question.objects.get_subclass(id=question_id)
- is_correct = question.check_if_correct(guess)
-
- if is_correct is True:
- outcome = "correct"
- sitting.add_to_score(1)
- user_progress_score_update(request, question.category, 1, 1)
- else:
- outcome = "incorrect"
- sitting.add_incorrect_question(question)
- user_progress_score_update(request, question.category, 0, 1)
-
- if quiz.answers_at_end is not True:
- return {'previous_answer': guess,
- 'previous_outcome': outcome,
- 'previous_question': question}
- else:
- return {}
-
-
-def user_progress_score_update(request, category, score, possible):
- try:
- progress = Progress.objects.get(user=request.user)
-
- except Progress.DoesNotExist:
- progress = Progress.objects.new_progress(request.user)
-
- progress.update_score(category, score, possible)
-
-
def anon_session_score(request, add=0, possible=0):
"""
Returns the session score for non-signed in users.