diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py index 1bfe48082933..3a43b5460893 100644 --- a/django/contrib/admin/views/main.py +++ b/django/contrib/admin/views/main.py @@ -236,16 +236,16 @@ def get_filters(self, request): int(month[-1] if month is not None else 1), int(day[-1] if day is not None else 1), ) - except ValueError as e: + if day: + to_date = from_date + timedelta(days=1) + elif month: + # In this branch, from_date will always be the first of + # a month, so advancing 32 days gives the next month. + to_date = (from_date + timedelta(days=32)).replace(day=1) + else: + to_date = from_date.replace(year=from_date.year + 1) + except (ValueError, OverflowError) as e: raise IncorrectLookupParameters(e) from e - if day: - to_date = from_date + timedelta(days=1) - elif month: - # In this branch, from_date will always be the first of a - # month, so advancing 32 days gives the next month. - to_date = (from_date + timedelta(days=32)).replace(day=1) - else: - to_date = from_date.replace(year=from_date.year + 1) if settings.USE_TZ: from_date = make_aware(from_date) to_date = make_aware(to_date) diff --git a/tests/admin_changelist/tests.py b/tests/admin_changelist/tests.py index dfec579f87cd..d0f339696d4a 100644 --- a/tests/admin_changelist/tests.py +++ b/tests/admin_changelist/tests.py @@ -469,6 +469,22 @@ def test_result_list_editable(self): with self.assertRaises(IncorrectLookupParameters): m.get_changelist_instance(request) + def test_date_hierarchy_out_of_range(self): + """ + An out-of-range year in a date_hierarchy lookup raises + IncorrectLookupParameters rather than letting ValueError or + OverflowError propagate (which would surface as an HTTP 500). + """ + m = EventAdmin(Event, custom_site) + # "9999" builds a valid from_date but to_date's year + 1 == 10000 + # raises ValueError; the huge value raises OverflowError in datetime(). + for invalid_year in ["9999", "99999999999999999999"]: + with self.subTest(year=invalid_year): + request = self.factory.get("/event/", data={"date__year": invalid_year}) + request.user = self.superuser + with self.assertRaises(IncorrectLookupParameters): + m.get_changelist_instance(request) + @skipUnlessDBFeature("uses_savepoints") def test_list_editable_atomicity(self): a = Swallow.objects.create(origin="Swallow A", load=4, speed=1)