diff --git a/polls/migrations/0002_question_end_date_alter_question_pub_date.py b/polls/migrations/0002_question_end_date_alter_question_pub_date.py new file mode 100644 index 0000000..56fe44f --- /dev/null +++ b/polls/migrations/0002_question_end_date_alter_question_pub_date.py @@ -0,0 +1,24 @@ +# Generated by Django 4.2.4 on 2023-09-05 13:47 + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('polls', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='question', + name='end_date', + field=models.DateTimeField(null=True, verbose_name='date ended'), + ), + migrations.AlterField( + model_name='question', + name='pub_date', + field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='date published'), + ), + ] diff --git a/polls/models.py b/polls/models.py index 7252b32..4e42bb7 100644 --- a/polls/models.py +++ b/polls/models.py @@ -26,7 +26,8 @@ class Question(models.Model): """ question_text = models.CharField(max_length=200) - pub_date = models.DateTimeField("date published") + pub_date = models.DateTimeField("date published", default=timezone.now) + end_date = models.DateTimeField("date ended", null=True) def was_published_recently(self): """ @@ -53,6 +54,28 @@ class Question(models.Model): """ return self.question_text + def is_published(self): + """ + Checks if the question is published or not. + + Returns: + bool: True if the question is published, else False. + """ + now = timezone.now() + return now >= self.pub_date + + def can_vote(self): + """ + Checks if the question can be voted on or not. + + Returns: + bool: True if the question is published and not ended, else False. + """ + now = timezone.now() + if self.end_date is None: + return self.pub_date <= now + return self.pub_date <= now <= self.end_date + class Choice(models.Model): """ diff --git a/polls/static/polls/style.css b/polls/static/polls/style.css deleted file mode 100644 index e69de29..0000000 diff --git a/polls/templates/polls/home.html b/polls/templates/polls/home.html index ad8a1c8..14a995a 100644 --- a/polls/templates/polls/home.html +++ b/polls/templates/polls/home.html @@ -10,7 +10,7 @@

Recent Polls

-

Total number of polls: {{ total_polls }}

+

Total number of polls: {{ total_open_polls }}

{% if latest_question_list %} {% for question in latest_question_list %} diff --git a/polls/tests.py b/polls/tests.py index d740da3..fb49a5d 100644 --- a/polls/tests.py +++ b/polls/tests.py @@ -37,6 +37,64 @@ class QuestionModelTests(TestCase): self.assertIs(recent_question.was_published_recently(), True) + def test_is_published_with_future_question(self): + """ + is_published() should return False for questions whos pub_date is in the + future. + """ + future_date = timezone.now() + datetime.timedelta(days=30) + future_question = Question(pub_date=future_date) + self.assertIs(future_question.is_published(), False) + + def test_is_published_with_past_question(self): + """ + is_published() should return True for questions whose pub_date is in the + past. + """ + past_date = timezone.now() - datetime.timedelta(days=1) + past_question = Question(pub_date=past_date) + self.assertIs(past_question.is_published(), True) + + def test_can_vote_with_question_not_ended(self): + """ + can_vote() should return True for questions that are published and have not + ended. + """ + pub_date = timezone.now() - datetime.timedelta(hours=1) + end_date = timezone.now() + datetime.timedelta(hours=1) + question = Question(pub_date=pub_date, end_date=end_date) + self.assertIs(question.can_vote(), True) + + def test_can_vote_with_question_ended(self): + """ + can_vote() should return False for questions that are published but have + ended. + """ + pub_date = timezone.now() - datetime.timedelta(hours=2) + end_date = timezone.now() - datetime.timedelta(hours=1) + question = Question(pub_date=pub_date, end_date=end_date) + self.assertIs(question.can_vote(), False) + + def test_can_vote_with_question_no_end_date(self): + """ + can_vote() should return True for questions that are published and have no + specified end date. + """ + pub_date = timezone.now() - datetime.timedelta(hours=1) + question = Question(pub_date=pub_date, end_date=None) + self.assertIs(question.can_vote(), True) + + def test_can_vote_with_question_ending_in_future(self): + """ + can_vote() should return False for questions that are published but have + an end date in the future. + """ + pub_date = timezone.now() - datetime.timedelta(hours=1) + end_date = timezone.now() + datetime.timedelta(hours=2) + question = Question(pub_date=pub_date, end_date=end_date) + self.assertIs(question.can_vote(), False) + + def create_question(question_text, days): """ Create a question with the given `question_text` and published the diff --git a/polls/views.py b/polls/views.py index 6180804..4c058fa 100644 --- a/polls/views.py +++ b/polls/views.py @@ -17,8 +17,14 @@ class HomeView(TemplateView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['latest_question_list'] = Question.objects.filter(pub_date__lte=timezone.now()).order_by("-pub_date")[:5] - context['total_polls'] = Question.objects.count() + all_questions = Question.objects.all() + #* Check if the question is published and can be voted. Then, sort by pub_date + published_questions = [q for q in all_questions if q.is_published() and q.can_vote()] + latest_published_questions = sorted(published_questions, key=lambda q: q.pub_date, reverse=True)[:5] + + context['latest_question_list'] = latest_published_questions + context['total_open_polls'] = sum(1 for q in published_questions if q.end_date is None) + context['total_polls'] = all_questions.count() return context diff --git a/requirements.txt b/requirements.txt index 63393f6..08e2adf 100644 Binary files a/requirements.txt and b/requirements.txt differ