From: Tom Walker Date: Mon, 7 Jul 2014 22:05:23 +0000 (+0100) Subject: trimming down bloat from quiz/views.py, used CBV as the starting page X-Git-Url: https://git.parisson.com/?a=commitdiff_plain;h=455fda61c7575ae76ae1893f08128303a0e10beb;p=django_quiz.git trimming down bloat from quiz/views.py, used CBV as the starting page for a quiz --- diff --git a/quiz/models.py b/quiz/models.py index ddf455e..36be085 100644 --- a/quiz/models.py +++ b/quiz/models.py @@ -342,7 +342,7 @@ class Sitting(models.Model): 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 diff --git a/quiz/templates/question.html b/quiz/templates/question.html index a939c61..382846a 100644 --- a/quiz/templates/question.html +++ b/quiz/templates/question.html @@ -15,11 +15,11 @@

The previous question:

{{ previous.previous_question }}

- {% ifequal previous.previous_outcome 'correct' %} + {% if previous.previous_outcome %}
{% else %}
- {% endifequal %} + {% endif %}

Your answer was {{ previous.previous_outcome }}

diff --git a/quiz/templates/quiz/quiz_detail.html b/quiz/templates/quiz/quiz_detail.html new file mode 100644 index 0000000..e20f500 --- /dev/null +++ b/quiz/templates/quiz/quiz_detail.html @@ -0,0 +1,14 @@ +{% extends 'base.html' %} +{% block title %} +{{ quiz.title }} +{% endblock %} + +{% block content %} +

{{ quiz.title }}

+

Category: {{ quiz.category }}

+{% if quiz.single_attempt %} +

You will only get one attempt at this quiz.

+{% endif %} +

{{ quiz.description }}

+

Start quiz

+{% endblock %} diff --git a/quiz/tests.py b/quiz/tests.py index cde453e..4c98f93 100644 --- a/quiz/tests.py +++ b/quiz/tests.py @@ -161,16 +161,16 @@ class TestSitting(TestCase): 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) @@ -225,7 +225,8 @@ class TestNonQuestionViews(TestCase): 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', @@ -270,6 +271,14 @@ class TestNonQuestionViews(TestCase): 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): @@ -301,13 +310,13 @@ 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) @@ -327,7 +336,7 @@ class TestQuestionViewsAnon(TestCase): 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) @@ -335,12 +344,12 @@ class TestQuestionViewsAnon(TestCase): 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]}) @@ -360,7 +369,7 @@ class TestQuestionViewsAnon(TestCase): 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]}) @@ -382,11 +391,11 @@ class TestQuestionViewsAnon(TestCase): 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]}) @@ -396,7 +405,7 @@ class TestQuestionViewsAnon(TestCase): 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') @@ -454,7 +463,7 @@ class TestQuestionViewsUser(TestCase): 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() @@ -472,7 +481,7 @@ class TestQuestionViewsUser(TestCase): 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 @@ -481,22 +490,22 @@ class TestQuestionViewsUser(TestCase): 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}) @@ -519,7 +528,7 @@ class TestQuestionViewsUser(TestCase): 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}) @@ -529,14 +538,14 @@ class TestQuestionViewsUser(TestCase): 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}) @@ -561,15 +570,15 @@ class TestQuestionViewsUser(TestCase): 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') diff --git a/quiz/urls.py b/quiz/urls.py index 63826c0..f56fb50 100644 --- a/quiz/urls.py +++ b/quiz/urls.py @@ -1,11 +1,11 @@ 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'), @@ -14,19 +14,17 @@ urlpatterns = patterns('quiz.views', view=CategoriesListView.as_view(), name='quiz_category_list_all'), - # quiz category: list quizzes url(regex=r'^category/(?P[\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[\w-]+)/$', - view='quiz_take', + url(regex=r'^(?P[\w-]+)/$', + view=QuizDetailView.as_view(), name='quiz_start_page'), url(regex=r'^(?P[\w-]+)/take/$', diff --git a/quiz/views.py b/quiz/views.py index 9c2374a..2f58fd9 100644 --- a/quiz/views.py +++ b/quiz/views.py @@ -4,7 +4,7 @@ from django.contrib.auth.decorators import login_required 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 @@ -13,6 +13,11 @@ class QuizListView(ListView): model = Quiz +class QuizDetailView(DetailView): + model = Quiz + slug_field = 'url' + + class CategoriesListView(ListView): model = Category @@ -60,36 +65,32 @@ def quiz_take(request, quiz_name): 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: @@ -132,16 +133,6 @@ def new_anon_quiz_session(request, quiz): 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 = {} @@ -191,13 +182,30 @@ def load_anon_next_question(request, quiz): 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 @@ -315,39 +323,6 @@ def question_check_anon(request, quiz): 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.