diff --git a/LCAdmin/polls/models.py b/LCAdmin/polls/models.py index 416d357..d101285 100644 --- a/LCAdmin/polls/models.py +++ b/LCAdmin/polls/models.py @@ -10,8 +10,8 @@ class Question(models.Model): return self.question_text def was_published_recently(self): - return self.pub_date >= timezone.now() - datetime.timedelta(days=1) - + now = timezone.now() + return now - datetime.timedelta(days=1) <= self.pub_date <= now class Choice(models.Model): question = models.ForeignKey(Question, on_delete=models.CASCADE) diff --git a/LCAdmin/polls/templates/polls/detail.html b/LCAdmin/polls/templates/polls/detail.html new file mode 100644 index 0000000..55fa300 --- /dev/null +++ b/LCAdmin/polls/templates/polls/detail.html @@ -0,0 +1,12 @@ +
+ {% csrf_token %} +
+

{{ question.question_text }}

+ {% if error_message %}

{{ error_message }}

{% endif %} + {% for choice in question.choice_set.all %} + +
+ {% endfor %} +
+ +
\ No newline at end of file diff --git a/LCAdmin/polls/templates/polls/details.html b/LCAdmin/polls/templates/polls/details.html deleted file mode 100644 index 4e1bd67..0000000 --- a/LCAdmin/polls/templates/polls/details.html +++ /dev/null @@ -1,6 +0,0 @@ -

{{ question.question_text }}

- \ No newline at end of file diff --git a/LCAdmin/polls/templates/polls/results.html b/LCAdmin/polls/templates/polls/results.html new file mode 100644 index 0000000..33b67b2 --- /dev/null +++ b/LCAdmin/polls/templates/polls/results.html @@ -0,0 +1,9 @@ +

{{ question.question_text }}

+ + + +Vote again? \ No newline at end of file diff --git a/LCAdmin/polls/tests.py b/LCAdmin/polls/tests.py index 7ce503c..21ce362 100644 --- a/LCAdmin/polls/tests.py +++ b/LCAdmin/polls/tests.py @@ -1,3 +1,36 @@ -from django.test import TestCase +import datetime -# Create your tests here. +from django.test import TestCase +from django.utils import timezone + +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) \ No newline at end of file diff --git a/LCAdmin/polls/urls.py b/LCAdmin/polls/urls.py index b124599..a98da1b 100644 --- a/LCAdmin/polls/urls.py +++ b/LCAdmin/polls/urls.py @@ -1,10 +1,11 @@ from django.urls import path from . import views + app_name = 'polls' urlpatterns = [ - path('', views.index, name='index'), - path('/', views.detail, name='detail'), - path('/results/', views.results, name='results'), + path('', views.IndexView.as_view(), name='index'), + path('/', views.DetailView.as_view(), name='detail'), + path('/results/', views.ResultsView.as_view(), name='results'), path('/vote/', views.vote, name='vote'), ] \ No newline at end of file diff --git a/LCAdmin/polls/views.py b/LCAdmin/polls/views.py index ca0fea2..70c4dbb 100644 --- a/LCAdmin/polls/views.py +++ b/LCAdmin/polls/views.py @@ -1,22 +1,47 @@ -from django.shortcuts import render -from django.http import HttpResponse +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 .models import Question +from .models import Choice, Question -def index(request): - latest_question_list = Question.objects.order_by('-pub_date')[:5] - context = {'latest_question_list': latest_question_list} - return render(request, 'polls/index.html', context) +class IndexView(generic.ListView): + template_name = 'polls/index.html' + context_object_name = 'latest_question_list' + + def get_queryset(self): + """Return the last five published questions.""" + return Question.objects.order_by('-pub_date')[:5] + + +class DetailView(generic.DetailView): + model = Question + template_name = 'polls/detail.html' + + +class ResultsView(generic.DetailView): + model = Question + template_name = 'polls/results.html' -def detail(request, question_id): - question = get_object_or_404(Question, pk=question_id) - return render(request, 'polls/detail.html', {'question': question}) -def results(request, question_id): - response = "You're looking at the results of question %s." - return HttpResponse(response % question_id) def vote(request, question_id): - return HttpResponse("You're voting on question %s." % question_id) \ No newline at end of file + question = get_object_or_404(Question, pk=question_id) + try: + ## added type ignore to get rid of choice _set error + selected_choice = question.choice_set.get(pk=request.POST['choice']) # type: ignore + except (KeyError, Choice.DoesNotExist): + # Redisplay the question voting form. + return render(request, 'polls/detail.html', { + 'question': question, + 'error_message': "You didn't select a choice.", + }) + else: + selected_choice.votes += 1 + selected_choice.save() + # Always return an HttpResponseRedirect after successfully dealing + # with POST data. This prevents data from being posted twice if a + # user hits the Back button. + ## type ignore bs + return HttpResponseRedirect(reverse('polls:results', args=(question.id,))) # type: ignore # type: ignore) \ No newline at end of file