django: complete tutorial #5

This commit is contained in:
Kyle Isom 2018-05-07 01:12:14 -07:00
parent d7d7b195d8
commit 92a5117dfc
5 changed files with 106 additions and 3 deletions

View File

@ -1,6 +1,8 @@
from django.db import models from django.db import models
from django.utils import timezone from django.utils import timezone
recent = timezone.timedelta(days=1)
class Question(models.Model): class Question(models.Model):
question_text = models.CharField(max_length=200) question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published') pub_date = models.DateTimeField('date published')
@ -9,7 +11,7 @@ class Question(models.Model):
return self.question_text return self.question_text
def was_published_recently(self): 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): class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE) question = models.ForeignKey(Question, on_delete=models.CASCADE)

View File

@ -0,0 +1,9 @@
<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
<li>{{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li>
{% endfor %}
</ul>
<a href="{% url 'polls:detail' question.id %}">Vote again?</a>

View File

@ -1,3 +1,88 @@
import datetime
from django.test import TestCase 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. # 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'],
['<Question: Past question.>']
)
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'],
['<Question: Past question 2.>', '<Question: Past question 1.>']
)
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)

View File

@ -1,6 +1,7 @@
from django.shortcuts import get_object_or_404, render from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.urls import reverse from django.urls import reverse
from django.utils import timezone
from django.views import generic from django.views import generic
from .models import Choice, Question from .models import Choice, Question
@ -11,13 +12,19 @@ class IndexView(generic.ListView):
def get_queryset(self): def get_queryset(self):
"""Returns the last five published questions.""" """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): class DetailView(generic.DetailView):
model = Question model = Question
template_name = 'polls/detail.html' 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): class ResultsView(generic.DetailView):
model = Question model = Question

View File

@ -1,3 +1,3 @@
https://docs.djangoproject.com/en/2.0/intro/tutorial03/ 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/tutorial04/
https://docs.djangoproject.com/en/2.0/intro/tutorial06/