diff --git a/django/views/generic/dates.py b/django/views/generic/dates.py index 2dd8883fa0..fa8d6e8506 100644 --- a/django/views/generic/dates.py +++ b/django/views/generic/dates.py @@ -70,7 +70,7 @@ class MonthMixin(object): Get the previous valid month. """ first_day, last_day = _month_bounds(date) - prev = (first_day - datetime.timedelta(days=1)).replace(day=1) + prev = (first_day - datetime.timedelta(days=1)) return _get_next_prev_month(self, prev, is_previous=True, use_first_day=True) @@ -516,7 +516,7 @@ def _get_next_prev_month(generic_view, naive_result, is_previous, use_first_day) This is a bit complicated since it handles both next and previous months and days (for MonthArchiveView and DayArchiveView); hence the coupling to generic_view. - However in essance the logic comes down to: + However in essence the logic comes down to: * If allow_empty and allow_future are both true, this is easy: just return the naive result (just the next/previous day or month, @@ -546,7 +546,7 @@ def _get_next_prev_month(generic_view, naive_result, is_previous, use_first_day) # whose date_field is at least (greater than/less than) the given # naive result else: - # Construct a lookup and an ordering depending on weather we're doing + # Construct a lookup and an ordering depending on whether we're doing # a previous date or a next date lookup. if is_previous: lookup = {'%s__lte' % date_field: naive_result} @@ -569,7 +569,7 @@ def _get_next_prev_month(generic_view, naive_result, is_previous, use_first_day) result = result.date() # For month views, we always want to have a date that's the first of the - # month for consistancy's sake. + # month for consistency's sake. if result and use_first_day: result = result.replace(day=1) diff --git a/tests/regressiontests/generic_views/dates.py b/tests/regressiontests/generic_views/dates.py index 09d52c1859..aa453ba2f2 100644 --- a/tests/regressiontests/generic_views/dates.py +++ b/tests/regressiontests/generic_views/dates.py @@ -198,6 +198,29 @@ class MonthArchiveViewTests(TestCase): res = self.client.get('/dates/books/2007/no_month/') self.assertEqual(res.status_code, 404) + def test_previous_month_without_content(self): + "Content can exist on any day of the previous month. Refs #14711" + self.pubdate_list = [ + datetime.date(2010, month, day) + for month,day in ((9,1), (10,2), (11,3)) + ] + for pubdate in self.pubdate_list: + name = str(pubdate) + Book.objects.create(name=name, slug=name, pages=100, pubdate=pubdate) + + res = self.client.get('/dates/books/2010/nov/allow_empty/') + self.assertEqual(res.status_code, 200) + self.assertEqual(res.context['previous_month'], datetime.date(2010,10,1)) + # The following test demonstrates the bug + res = self.client.get('/dates/books/2010/nov/') + self.assertEqual(res.status_code, 200) + self.assertEqual(res.context['previous_month'], datetime.date(2010,10,1)) + # The bug does not occur here because a Book with pubdate of Sep 1 exists + res = self.client.get('/dates/books/2010/oct/') + self.assertEqual(res.status_code, 200) + self.assertEqual(res.context['previous_month'], datetime.date(2010,9,1)) + + class WeekArchiveViewTests(TestCase): fixtures = ['generic-views-test-data.json'] urls = 'regressiontests.generic_views.urls' @@ -359,3 +382,4 @@ class DateDetailViewTests(TestCase): def test_invalid_url(self): self.assertRaises(AttributeError, self.client.get, "/dates/books/2008/oct/01/nopk/") +