Skip to content

Commit d19b30f

Browse files
authored
Sort downloads table by version (#2822)
1 parent c589e2f commit d19b30f

File tree

5 files changed

+61
-15
lines changed

5 files changed

+61
-15
lines changed

downloads/tests/base.py

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import datetime
1+
import datetime as dt
22

33
from django.test import TestCase
44
from django.utils import timezone
@@ -32,7 +32,7 @@ def setUp(self):
3232
is_latest=True,
3333
is_published=True,
3434
release_page=self.release_275_page,
35-
release_date=timezone.now() - datetime.timedelta(days=-1)
35+
release_date=dt.datetime.fromisoformat("2013-05-15T00:00Z"),
3636
)
3737
self.release_275_windows_32bit = ReleaseFile.objects.create(
3838
os=self.windows,
@@ -102,9 +102,31 @@ def setUp(self):
102102

103103
self.python_3 = Release.objects.create(
104104
version=Release.PYTHON3,
105-
name='Python 3.10',
105+
name="Python 3.10.19",
106106
is_latest=True,
107107
is_published=True,
108108
show_on_download_page=True,
109-
release_page=self.release_275_page
109+
release_page=self.release_275_page,
110+
release_date=dt.datetime.fromisoformat("2025-10-09T00:00Z"),
111+
)
112+
113+
self.python_3_10_18 = Release.objects.create(
114+
version=Release.PYTHON3,
115+
name="Python 3.10.18",
116+
is_published=True,
117+
release_date=dt.datetime.fromisoformat("2025-06-03T00:00Z"),
118+
)
119+
120+
self.python_3_8_20 = Release.objects.create(
121+
version=Release.PYTHON3,
122+
name="Python 3.8.20",
123+
is_published=True,
124+
release_date=dt.datetime.fromisoformat("2024-09-06T00:00Z"),
125+
)
126+
127+
self.python_3_8_19 = Release.objects.create(
128+
version=Release.PYTHON3,
129+
name="Python 3.8.19",
130+
is_published=True,
131+
release_date=dt.datetime.fromisoformat("2024-03-19T00:00Z"),
110132
)

downloads/tests/test_models.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@ def test_stringification(self):
1010

1111
def test_published(self):
1212
published_releases = Release.objects.published()
13-
self.assertEqual(len(published_releases), 4)
13+
self.assertEqual(len(published_releases), 7)
1414
self.assertIn(self.release_275, published_releases)
1515
self.assertIn(self.hidden_release, published_releases)
1616
self.assertNotIn(self.draft_release, published_releases)
1717

1818
def test_release(self):
1919
released_versions = Release.objects.released()
20-
self.assertEqual(len(released_versions), 3)
20+
self.assertEqual(len(released_versions), 6)
2121
self.assertIn(self.release_275, released_versions)
2222
self.assertIn(self.hidden_release, released_versions)
2323
self.assertNotIn(self.draft_release, released_versions)
@@ -37,7 +37,7 @@ def test_draft(self):
3737

3838
def test_downloads(self):
3939
downloads = Release.objects.downloads()
40-
self.assertEqual(len(downloads), 2)
40+
self.assertEqual(len(downloads), 5)
4141
self.assertIn(self.release_275, downloads)
4242
self.assertNotIn(self.hidden_release, downloads)
4343
self.assertNotIn(self.draft_release, downloads)
@@ -50,7 +50,7 @@ def test_python2(self):
5050

5151
def test_python3(self):
5252
versions = Release.objects.python3()
53-
self.assertEqual(len(versions), 3)
53+
self.assertEqual(len(versions), 6)
5454
self.assertNotIn(self.release_275, versions)
5555
self.assertNotIn(self.draft_release, versions)
5656
self.assertIn(self.hidden_release, versions)

downloads/tests/test_views.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,21 @@ def test_download(self):
5656
response = self.client.get(url)
5757
self.assertEqual(response.status_code, 200)
5858

59+
def test_download_releases_ordered_by_version(self):
60+
url = reverse("download:download")
61+
response = self.client.get(url)
62+
releases = response.context["releases"]
63+
self.assertEqual(
64+
releases,
65+
[
66+
self.python_3,
67+
self.python_3_10_18,
68+
self.python_3_8_20,
69+
self.python_3_8_19,
70+
self.release_275,
71+
],
72+
)
73+
5974
def test_latest_redirects(self):
6075
latest_python2 = Release.objects.released().python2().latest()
6176
url = reverse('download:download_latest_python2')
@@ -218,13 +233,13 @@ def test_get_release(self):
218233
self.assertEqual(response.status_code, 200)
219234
content = self.get_json(response)
220235
# 'self.draft_release' won't shown here.
221-
self.assertEqual(len(content), 4)
236+
self.assertEqual(len(content), 7)
222237

223238
# Login to get all releases.
224239
response = self.client.get(url, headers={"authorization": self.Authorization})
225240
self.assertEqual(response.status_code, 200)
226241
content = self.get_json(response)
227-
self.assertEqual(len(content), 5)
242+
self.assertEqual(len(content), 8)
228243
self.assertFalse(content[0]['is_latest'])
229244

230245
def test_post_release(self):
@@ -594,5 +609,5 @@ def test_feed_item_count(self) -> None:
594609
response = self.client.get(self.url)
595610
content = response.content.decode()
596611

597-
# In BaseDownloadTests, we create 5 releases, 4 of which are published, 1 of those published are hidden..
598-
self.assertEqual(content.count("<item>"), 4)
612+
# In BaseDownloadTests, we create 8 releases, 7 of which are published, 1 of those published are hidden..
613+
self.assertEqual(content.count("<item>"), 7)

downloads/views.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,17 @@ def get_context_data(self, **kwargs):
124124
data['pymanager'] = latest_pymanager.download_file_for_os(o.slug)
125125
python_files.append(data)
126126

127+
def version_key(release: Release) -> tuple[int, ...]:
128+
try:
129+
return tuple(int(x) for x in release.get_version().split("."))
130+
except ValueError:
131+
return (0,)
132+
133+
releases = list(Release.objects.downloads())
134+
releases.sort(key=version_key, reverse=True)
135+
127136
context.update({
128-
'releases': Release.objects.downloads(),
137+
'releases': releases,
129138
'latest_python2': latest_python2,
130139
'latest_python3': latest_python3,
131140
'python_files': python_files,

templates/downloads/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ <h1 class="call-to-action">Download the latest version of Python</h1>
5050
<div class="row active-release-list-widget">
5151
{% render_active_banner %}
5252

53-
<h2 class="widget-title">Active Python Releases</h2>
53+
<h2 class="widget-title">Active Python releases</h2>
5454
<p class="success-quote"><a href="https://devguide.python.org/versions/#versions">For more information visit the Python Developer's Guide</a>.</p>
5555

5656
{% box 'downloads-active-releases' %}
@@ -74,7 +74,7 @@ <h2 class="widget-title">Looking for a specific release?</h2>
7474
<span class="release-number"><a href="{{ r.get_absolute_url }}">{{ r.name }}</a></span>
7575
<span class="release-date">{{ r.release_date|date }}</span>
7676
<span class="release-download"><a href="{{ r.get_absolute_url }}"><span aria-hidden="true" class="icon-download"></span> Download</a></span>
77-
<span class="release-enhancements"><a href="{{ r.release_notes_url }}">Release Notes</a></span>
77+
<span class="release-enhancements"><a href="{{ r.release_notes_url }}">Release notes</a></span>
7878
</li>
7979
{% endfor %}
8080
</ol>

0 commit comments

Comments
 (0)