Skip to content

Commit e2ac65b

Browse files
zoobaJacobCoffee
andauthored
Update website for Python install manager (#2717)
Co-authored-by: Jacob Coffee <[email protected]>
1 parent 1efbb24 commit e2ac65b

File tree

8 files changed

+85
-1
lines changed

8 files changed

+85
-1
lines changed

downloads/managers.py

+13
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,18 @@ def python2(self):
2323
def python3(self):
2424
return self.filter(version=3, is_published=True)
2525

26+
def pymanager(self):
27+
return self.filter(version=100, is_published=True)
28+
2629
def latest_python2(self):
2730
return self.python2().filter(is_latest=True)
2831

2932
def latest_python3(self):
3033
return self.python3().filter(is_latest=True)
3134

35+
def latest_pymanager(self):
36+
return self.pymanager().filter(is_latest=True)
37+
3238
def pre_release(self):
3339
return self.filter(pre_release=True)
3440

@@ -50,3 +56,10 @@ def latest_python3(self):
5056
return qs[0]
5157
else:
5258
return None
59+
60+
def latest_pymanager(self):
61+
qs = self.get_queryset().latest_pymanager()
62+
if qs:
63+
return qs[0]
64+
else:
65+
return None
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Generated by Django 4.2.20 on 2025-04-24 19:26
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('downloads', '0011_alter_os_creator_alter_os_last_modified_by_and_more'),
10+
]
11+
12+
operations = [
13+
migrations.AlterField(
14+
model_name='release',
15+
name='version',
16+
field=models.IntegerField(choices=[(3, 'Python 3.x.x'), (2, 'Python 2.x.x'), (1, 'Python 1.x.x'), (100, 'Python install manager')], default=3),
17+
),
18+
]

downloads/models.py

+6
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,12 @@ class Release(ContentManageable, NameSlugModel):
4545
PYTHON1 = 1
4646
PYTHON2 = 2
4747
PYTHON3 = 3
48+
PYMANAGER = 100
4849
PYTHON_VERSION_CHOICES = (
4950
(PYTHON3, 'Python 3.x.x'),
5051
(PYTHON2, 'Python 2.x.x'),
5152
(PYTHON1, 'Python 1.x.x'),
53+
(PYMANAGER, 'Python install manager'),
5254
)
5355
version = models.IntegerField(default=PYTHON3, choices=PYTHON_VERSION_CHOICES)
5456
is_latest = models.BooleanField(
@@ -146,6 +148,10 @@ def is_version_at_least_3_5(self):
146148
def is_version_at_least_3_9(self):
147149
return self.is_version_at_least((3, 9))
148150

151+
@property
152+
def is_version_at_least_3_14(self):
153+
return self.is_version_at_least((3, 14))
154+
149155

150156
def update_supernav():
151157
latest_python3 = Release.objects.latest_python3()

downloads/urls.py

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
urlpatterns = [
66
re_path(r'latest/python2/?$', views.DownloadLatestPython2.as_view(), name='download_latest_python2'),
77
re_path(r'latest/python3/?$', views.DownloadLatestPython3.as_view(), name='download_latest_python3'),
8+
re_path(r'latest/pymanager/?$', views.DownloadLatestPyManager.as_view(), name='download_latest_pymanager'),
89
re_path(r'latest/?$', views.DownloadLatestPython3.as_view(), name='download_latest_python3'),
910
path('operating-systems/', views.DownloadFullOSList.as_view(), name='download_full_os_list'),
1011
path('release/<slug:release_slug>/', views.DownloadReleaseDetail.as_view(), name='download_release_detail'),

downloads/views.py

+21
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,30 @@ def get_redirect_url(self, **kwargs):
4545
return reverse('download')
4646

4747

48+
class DownloadLatestPyManager(RedirectView):
49+
""" Redirect to latest Python install manager release """
50+
permanent = False
51+
52+
def get_redirect_url(self, **kwargs):
53+
try:
54+
latest_pymanager = Release.objects.latest_pymanager()
55+
except Release.DoesNotExist:
56+
latest_pymanager = None
57+
58+
if latest_pymanager:
59+
return latest_pymanager.get_absolute_url()
60+
else:
61+
return reverse('downloads')
62+
63+
4864
class DownloadBase:
4965
""" Include latest releases in all views """
5066
def get_context_data(self, **kwargs):
5167
context = super().get_context_data(**kwargs)
5268
context.update({
5369
'latest_python2': Release.objects.latest_python2(),
5470
'latest_python3': Release.objects.latest_python3(),
71+
'latest_pymanager': Release.objects.latest_pymanager(),
5572
})
5673
return context
5774

@@ -71,6 +88,8 @@ def get_context_data(self, **kwargs):
7188
except Release.DoesNotExist:
7289
latest_python3 = None
7390

91+
latest_pymanager = context.get('latest_pymanager')
92+
7493
python_files = []
7594
for o in OS.objects.all():
7695
data = {
@@ -80,6 +99,8 @@ def get_context_data(self, **kwargs):
8099
data['python2'] = latest_python2.download_file_for_os(o.slug)
81100
if latest_python3 is not None:
82101
data['python3'] = latest_python3.download_file_for_os(o.slug)
102+
if latest_pymanager is not None:
103+
data['pymanager'] = latest_pymanager.download_file_for_os(o.slug)
83104
python_files.append(data)
84105

85106
context.update({

templates/downloads/index.html

+9
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,20 @@ <h1 class="call-to-action">Download the latest source release</h1>
1717
{% else %}
1818
<h1 class="call-to-action">Download the latest version for {{ data.os.name }}</h1>
1919
{% endif %}
20+
{% if data.pymanager %}
21+
<p class="download-buttons">
22+
<a class="button" href="{{ data.pymanager.url }}">Download Python install manager</a>
23+
</p>
24+
{% if data.python3 %}
25+
<p>Or get the standalone installer for <a href="{{ data.python3.url }}">{{ data.python3.release.name }}</a></p>
26+
{% endif %}
27+
{% else %}
2028
<p class="download-buttons">
2129
{% if data.python3 %}
2230
<a class="button" href="{{ data.python3.url }}">Download {{ data.python3.release.name }}</a>
2331
{% endif %}
2432
</p>
33+
{% endif %}
2534
</div>
2635
{% endfor %}
2736
<div class="download-unknown">

templates/downloads/os_list.html

+11-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ <h1 class="page-title">Python Releases for {{ os.name }}</h1>
2929
</header>
3030

3131
<ul>
32+
{% if os.slug == 'windows' and latest_pymanager %}
33+
<li><a href="{{ latest_pymanager.get_absolute_url }}">Latest Python install manager - {{ latest_pymanager.name }}</a></li>
34+
{% endif %}
35+
3236
<li><a href="{{ latest_python3.get_absolute_url }}">Latest Python 3 Release - {{ latest_python3.name }}</a></li>
3337
</ul>
3438
<div class="col-row two-col">
@@ -39,7 +43,13 @@ <h2>Stable Releases</h2>
3943
<li>
4044
<a href="{{ r.get_absolute_url }}">{{ r.name }} - {{ r.release_date|date }}</a>
4145
{% if os.slug == 'windows' %}
42-
{% if r.is_version_at_least_3_9 %}
46+
{% if latest_pymanager and r.is_version_at_least_3_14 %}
47+
{% if latest_pymanager %}
48+
<p>Download using the <a href="{{ latest_pymanager.get_absolute_url }}">Python install manager</a>.</p>
49+
{% else %}
50+
<p>Download using the <a href="https://docs.python.org/using/windows.html">Python install manager</a>.</p>
51+
{% endif %}
52+
{% elif r.is_version_at_least_3_9 %}
4353
<p><strong>Note that {{ r.name }} <em>cannot</em> be used on Windows 7 or earlier.</strong></p>
4454
{% elif r.is_version_at_least_3_5 %}
4555
<p><strong>Note that {{ r.name }} <em>cannot</em> be used on Windows XP or earlier.</strong></p>

templates/downloads/supernav.html

+6
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,16 @@ <h3>Python Source</h3>
77
{% else %}
88
<h4>Download for {{ data.os.name }}</h4>
99
{% endif %}
10+
11+
{% if data.pymanager %}
12+
<p><a class="button" href="{{ data.pymanager.url }}">Python install manager</a></p>
13+
<p>Or get the standalone installer for <a class="button" href="{{ data.python3.url }}">{{ data.python3.release.name }}</a></p>
14+
{% else %}
1015
<p>
1116
<a class="button" href="{{ data.python3.url }}">{{ data.python3.release.name }}</a>
1217
</p>
1318
{% if data.os.slug == 'windows' %}<p><strong>Note that Python 3.9+ <em>cannot</em> be used on Windows 7 or earlier.</strong></p>{% endif %}
19+
{% endif %}
1420
<p>Not the OS you are looking for? Python can be used on many operating systems and environments. <a href="{% url 'download:download' %}">View the full list of downloads</a>.</p>
1521
</div>
1622
{% endfor %}

0 commit comments

Comments
 (0)