diff --git a/db.sqlite3 b/db.sqlite3 index b44bc11..1091471 100644 Binary files a/db.sqlite3 and b/db.sqlite3 differ diff --git a/polls/__pycache__/models.cpython-310.pyc b/polls/__pycache__/models.cpython-310.pyc index 278601c..bf6f61b 100644 Binary files a/polls/__pycache__/models.cpython-310.pyc and b/polls/__pycache__/models.cpython-310.pyc differ diff --git a/polls/__pycache__/views.cpython-310.pyc b/polls/__pycache__/views.cpython-310.pyc index 3066ff2..d3a2fae 100644 Binary files a/polls/__pycache__/views.cpython-310.pyc and b/polls/__pycache__/views.cpython-310.pyc differ diff --git a/polls/models.py b/polls/models.py index c9f2d1b..913f0bc 100644 --- a/polls/models.py +++ b/polls/models.py @@ -16,4 +16,8 @@ class Choice(models.Model): choice_text = models.CharField(max_length=200) votes = models.IntegerField(default=0) def __str__(self): - return self.choice_text \ No newline at end of file + return self.choice_text + +def was_published_recently(self): + now = timezone.now() + return now - datetime.timedelta(days=1) <= self.pub_date <= now \ No newline at end of file diff --git a/polls/tests.py b/polls/tests.py index 7ce503c..f513972 100644 --- a/polls/tests.py +++ b/polls/tests.py @@ -1,3 +1,124 @@ +import datetime from django.test import TestCase +from django.utils import timezone +from django.urls import reverse -# Create your tests here. +from .models import Question + + +class QuestionModelTests(TestCase): + def test_was_published_recently_with_future_question(self): + """ + was_published_recently() returns False for questions whose pub_date + is in the future. + """ + time = timezone.now() + datetime.timedelta(days=30) + future_question = Question(pub_date=time) + self.assertIs(future_question.was_published_recently(), False) + +def test_was_published_recently_with_old_question(self): + """ + was_published_recently() returns False for questions whose pub_date + is older than 1 day. + """ + time = timezone.now() - datetime.timedelta(days=1, seconds=1) + old_question = Question(pub_date=time) + self.assertIs(old_question.was_published_recently(), False) + + +def test_was_published_recently_with_recent_question(self): + """ + was_published_recently() returns True for questions whose pub_date + is within the last day. + """ + time = timezone.now() - datetime.timedelta(hours=23, minutes=59, seconds=59) + recent_question = Question(pub_date=time) + self.assertIs(recent_question.was_published_recently(), True) + +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 Question.objects.create(question_text=question_text, pub_date=time) + + +class QuestionIndexViewTests(TestCase): + def test_no_questions(self): + """ + If no questions exist, an appropriate message is displayed. + """ + response = self.client.get(reverse("polls:index")) + self.assertEqual(response.status_code, 200) + self.assertContains(response, "No polls are available.") + self.assertQuerySetEqual(response.context["latest_question_list"], []) + + def test_past_question(self): + """ + Questions with a pub_date in the past are displayed on the + index page. + """ + question = create_question(question_text="Past question.", days=-30) + response = self.client.get(reverse("polls:index")) + self.assertQuerySetEqual( + response.context["latest_question_list"], + [question], + ) + + def test_future_question(self): + """ + Questions with a pub_date in the future aren't displayed on + the index page. + """ + create_question(question_text="Future question.", days=30) + response = self.client.get(reverse("polls:index")) + self.assertContains(response, "No polls are available.") + self.assertQuerySetEqual(response.context["latest_question_list"], []) + + def test_future_question_and_past_question(self): + """ + Even if both past and future questions exist, only past questions + are displayed. + """ + question = 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_question_list"], + [question], + ) + + def test_two_past_questions(self): + """ + The questions index page may display multiple questions. + """ + question1 = create_question(question_text="Past question 1.", days=-30) + question2 = create_question(question_text="Past question 2.", days=-5) + response = self.client.get(reverse("polls:index")) + self.assertQuerySetEqual( + response.context["latest_question_list"], + [question2, question1], + ) + +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/polls/views.py b/polls/views.py index eb84752..554188c 100644 --- a/polls/views.py +++ b/polls/views.py @@ -3,9 +3,17 @@ from django.http import HttpResponseRedirect from django.shortcuts import get_object_or_404, render from django.urls import reverse from django.views import generic - +from django.utils import timezone from .models import Choice, Question +def get_queryset(self): + """ + Return the last five published questions (not including those set to be + published in the future). + """ + return Question.objects.filter(pub_date__lte=timezone.now()).order_by("-pub_date")[ + :5 + ] class IndexView(generic.ListView): template_name = "polls/index.html" @@ -19,6 +27,12 @@ class IndexView(generic.ListView): class DetailView(generic.DetailView): model = Question template_name = "polls/detail.html" + + def get_queryset(self): + """ + Excludes any questions that aren't published yet. + """ + return Question.objects.filter(pub_date__lte=timezone.now()) class ResultsView(generic.DetailView):