From 92a5117dfc1969fe6d1f914ed3c0860188ae3f0a Mon Sep 17 00:00:00 2001 From: Kyle Isom Date: Mon, 7 May 2018 01:12:14 -0700 Subject: [PATCH] django: complete tutorial #5 --- django/mysite/polls/models.py | 4 +- .../mysite/polls/templates/polls/results.html | 9 ++ django/mysite/polls/tests.py | 85 +++++++++++++++++++ django/mysite/polls/views.py | 9 +- django/mysite/progress.txt | 2 +- 5 files changed, 106 insertions(+), 3 deletions(-) create mode 100644 django/mysite/polls/templates/polls/results.html diff --git a/django/mysite/polls/models.py b/django/mysite/polls/models.py index 3a395db..f819cde 100644 --- a/django/mysite/polls/models.py +++ b/django/mysite/polls/models.py @@ -1,6 +1,8 @@ from django.db import models from django.utils import timezone +recent = timezone.timedelta(days=1) + class Question(models.Model): question_text = models.CharField(max_length=200) pub_date = models.DateTimeField('date published') @@ -9,7 +11,7 @@ class Question(models.Model): return self.question_text def was_published_recently(self): - return self.pub_date >= timezone.now() - timezone.timedelta(days=1) + return timezone.now() - recent <= self.pub_date <= timezone.now() class Choice(models.Model): question = models.ForeignKey(Question, on_delete=models.CASCADE) diff --git a/django/mysite/polls/templates/polls/results.html b/django/mysite/polls/templates/polls/results.html new file mode 100644 index 0000000..33b67b2 --- /dev/null +++ b/django/mysite/polls/templates/polls/results.html @@ -0,0 +1,9 @@ +

{{ question.question_text }}

+ + + +Vote again? \ No newline at end of file diff --git a/django/mysite/polls/tests.py b/django/mysite/polls/tests.py index 7ce503c..79b042a 100644 --- a/django/mysite/polls/tests.py +++ b/django/mysite/polls/tests.py @@ -1,3 +1,88 @@ +import datetime + from django.test import TestCase +from django.urls import reverse +from django.utils import timezone + +from . import models + +def create_question(question_text, days): + """ + Create a question with the given `question_text` and published the + given number of `days` offset to now (negative for questions published + in the past, positive for questions that have yet to be published). + """ + time = timezone.now() + datetime.timedelta(days=days) + return models.Question.objects.create(question_text=question_text, pub_date=time) # Create your tests here. +class QuestionModelTests(TestCase): + def test_was_published_recently(self): + """ + was_published_recently returns False for questions whose + pub_date is in the future. + """ + time = timezone.now() + datetime.timedelta(days=30) + future_question = models.Question(pub_date=time) + self.assertIs(future_question.was_published_recently(), False) + + def test_was_published_recently_with_old_question(self): + """ + was_published_recently should return False for questions whose + pub_date falls outside the 'recent' range. + """ + time = timezone.now() + (models.recent + datetime.timedelta(microseconds=1)) + old_question = models.Question(pub_date=time) + self.assertIs(old_question.was_published_recently(), False) + + def test_was_published_recently_with_recent_question(self): + # build a timestamp that falls just inside our recent gateway. + time = timezone.now() - (models.recent - datetime.timedelta(seconds=1)) + recent_question = models.Question(pub_date=time) + self.assertIs(recent_question.was_published_recently(), True) + + def test_future_question_and_past_question(self): + """ + Even if both past and future questions exist, only past questions + are displayed. + """ + create_question(question_text="Past question.", days=-30) + create_question(question_text="Future question.", days=30) + response = self.client.get(reverse('polls:index')) + self.assertQuerysetEqual( + response.context['latest_questions'], + [''] + ) + + def test_two_past_questions(self): + """ + The questions index page may display multiple questions. + """ + create_question(question_text="Past question 1.", days=-30) + create_question(question_text="Past question 2.", days=-5) + response = self.client.get(reverse('polls:index')) + self.assertQuerysetEqual( + response.context['latest_questions'], + ['', ''] + ) + +class QuestionDetailViewTests(TestCase): + def test_future_question(self): + """ + The detail view of a question with a pub_date in the future + returns a 404 not found. + """ + future_question = create_question(question_text='Future question.', days=5) + url = reverse('polls:detail', args=(future_question.id,)) + response = self.client.get(url) + self.assertEqual(response.status_code, 404) + + def test_past_question(self): + """ + The detail view of a question with a pub_date in the past + displays the question's text. + """ + past_question = create_question(question_text='Past Question.', days=-5) + url = reverse('polls:detail', args=(past_question.id,)) + response = self.client.get(url) + self.assertContains(response, past_question.question_text) \ No newline at end of file diff --git a/django/mysite/polls/views.py b/django/mysite/polls/views.py index 4d43931..6d5e91a 100644 --- a/django/mysite/polls/views.py +++ b/django/mysite/polls/views.py @@ -1,6 +1,7 @@ from django.shortcuts import get_object_or_404, render from django.http import HttpResponseRedirect from django.urls import reverse +from django.utils import timezone from django.views import generic from .models import Choice, Question @@ -11,13 +12,19 @@ class IndexView(generic.ListView): def get_queryset(self): """Returns the last five published questions.""" - return Question.objects.order_by('-pub_date')[:5] + return Question.objects.filter( + pub_date__lte=timezone.now(), + ).order_by('-pub_date')[:5] class DetailView(generic.DetailView): model = Question template_name = 'polls/detail.html' + def get_queryset(self): + """Don't incluce questions that aren't published yet/""" + return Question.objects.filter(pub_date__lte=timezone.now()) + class ResultsView(generic.DetailView): model = Question diff --git a/django/mysite/progress.txt b/django/mysite/progress.txt index 23a19a0..104086e 100644 --- a/django/mysite/progress.txt +++ b/django/mysite/progress.txt @@ -1,3 +1,3 @@ https://docs.djangoproject.com/en/2.0/intro/tutorial03/ https://docs.djangoproject.com/en/2.0/intro/tutorial04/ - +https://docs.djangoproject.com/en/2.0/intro/tutorial06/