From 2ee0186d2fd0c901cd8b9af6d42233c61da32b99 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Wed, 26 Nov 2025 19:28:02 +0200 Subject: [PATCH] Add 'superseded by' notice to older Python 3 releases --- downloads/tests/test_views.py | 31 +++++++++++++++++++++++++ downloads/views.py | 12 ++++++++++ templates/downloads/release_detail.html | 6 ++++- 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/downloads/tests/test_views.py b/downloads/tests/test_views.py index 5c5471d5a..247da04c8 100644 --- a/downloads/tests/test_views.py +++ b/downloads/tests/test_views.py @@ -46,6 +46,37 @@ def test_download_release_detail(self): response = self.client.get(url) self.assertEqual(response.status_code, 404) + def test_download_release_detail_not_superseded(self): + """Test that latest releases and Python 2 do not show a superseded notice.""" + for release in [self.python_3, self.python_3_8_20, self.release_275]: + with self.subTest(release=release.name): + url = reverse( + "download:download_release_detail", + kwargs={"release_slug": release.slug}, + ) + response = self.client.get(url) + self.assertEqual(response.status_code, 200) + self.assertNotIn("latest_in_series", response.context) + self.assertNotContains(response, "has been superseded by") + + def test_download_release_detail_superseded(self): + """Test that older releases show a superseded notice.""" + tests = [ + (self.python_3_10_18, self.python_3), + (self.python_3_8_19, self.python_3_8_20), + ] + for old_release, latest_release in tests: + with self.subTest(release=old_release.name): + url = reverse( + "download:download_release_detail", + kwargs={"release_slug": old_release.slug}, + ) + response = self.client.get(url) + self.assertEqual(response.status_code, 200) + self.assertEqual(response.context["latest_in_series"], latest_release) + self.assertContains(response, "has been superseded by") + self.assertContains(response, latest_release.name) + def test_download_os_list(self): url = reverse('download:download_os_list', kwargs={'slug': self.linux.slug}) response = self.client.get(url) diff --git a/downloads/views.py b/downloads/views.py index fd1141c14..41e8839ff 100644 --- a/downloads/views.py +++ b/downloads/views.py @@ -1,5 +1,6 @@ from typing import Any +import re from datetime import datetime from django.db.models import Case, IntegerField, Prefetch, When @@ -216,6 +217,17 @@ def get_context_data(self, **kwargs): ) ) + # Find the latest release in the feature series (such as 3.14.x) + # to show a "superseded by" notice on older releases + version = self.object.get_version() + if version and self.object.version == Release.PYTHON3: + match = re.match(r"^3\.(\d+)", version) + if match: + minor_version = int(match.group(1)) + latest_in_series = Release.objects.latest_python3(minor_version) + if latest_in_series and latest_in_series.pk != self.object.pk: + context["latest_in_series"] = latest_in_series + return context diff --git a/templates/downloads/release_detail.html b/templates/downloads/release_detail.html index 5959dfe30..4faf51749 100644 --- a/templates/downloads/release_detail.html +++ b/templates/downloads/release_detail.html @@ -26,7 +26,11 @@
Release Date: {{ release.release_date|date }}
+ {% if latest_in_series %} +Note: {{ release.name }} has been superseded by {{ latest_in_series.name }}.
+ {% endif %} + +Release date: {{ release.release_date|date }}
{% if release.content.raw %} {{ release.content.rendered|safe }}