Skip to content

Update website for Python install manager #2717

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions downloads/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,18 @@ def python2(self):
def python3(self):
return self.filter(version=3, is_published=True)

def pymanager(self):
return self.filter(version=100, is_published=True)

def latest_python2(self):
return self.python2().filter(is_latest=True)

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

def latest_pymanager(self):
return self.pymanager().filter(is_latest=True)

def pre_release(self):
return self.filter(pre_release=True)

Expand All @@ -50,3 +56,10 @@ def latest_python3(self):
return qs[0]
else:
return None

def latest_pymanager(self):
qs = self.get_queryset().latest_pymanager()
if qs:
return qs[0]
else:
return None
18 changes: 18 additions & 0 deletions downloads/migrations/0012_alter_release_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 4.2.20 on 2025-04-24 19:26

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('downloads', '0011_alter_os_creator_alter_os_last_modified_by_and_more'),
]

operations = [
migrations.AlterField(
model_name='release',
name='version',
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),
),
]
6 changes: 6 additions & 0 deletions downloads/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,12 @@ class Release(ContentManageable, NameSlugModel):
PYTHON1 = 1
PYTHON2 = 2
PYTHON3 = 3
PYMANAGER = 100
PYTHON_VERSION_CHOICES = (
(PYTHON3, 'Python 3.x.x'),
(PYTHON2, 'Python 2.x.x'),
(PYTHON1, 'Python 1.x.x'),
(PYMANAGER, 'Python install manager'),
)
version = models.IntegerField(default=PYTHON3, choices=PYTHON_VERSION_CHOICES)
is_latest = models.BooleanField(
Expand Down Expand Up @@ -146,6 +148,10 @@ def is_version_at_least_3_5(self):
def is_version_at_least_3_9(self):
return self.is_version_at_least((3, 9))

@property
def is_version_at_least_3_14(self):
return self.is_version_at_least((3, 14))


def update_supernav():
latest_python3 = Release.objects.latest_python3()
Expand Down
1 change: 1 addition & 0 deletions downloads/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
urlpatterns = [
re_path(r'latest/python2/?$', views.DownloadLatestPython2.as_view(), name='download_latest_python2'),
re_path(r'latest/python3/?$', views.DownloadLatestPython3.as_view(), name='download_latest_python3'),
re_path(r'latest/pymanager/?$', views.DownloadLatestPyManager.as_view(), name='download_latest_pymanager'),
re_path(r'latest/?$', views.DownloadLatestPython3.as_view(), name='download_latest_python3'),
path('operating-systems/', views.DownloadFullOSList.as_view(), name='download_full_os_list'),
path('release/<slug:release_slug>/', views.DownloadReleaseDetail.as_view(), name='download_release_detail'),
Expand Down
21 changes: 21 additions & 0 deletions downloads/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,30 @@ def get_redirect_url(self, **kwargs):
return reverse('download')


class DownloadLatestPyManager(RedirectView):
""" Redirect to latest Python install manager release """
permanent = False

def get_redirect_url(self, **kwargs):
try:
latest_pymanager = Release.objects.latest_pymanager()
except Release.DoesNotExist:
latest_pymanager = None

if latest_pymanager:
return latest_pymanager.get_absolute_url()
else:
return reverse('download')


class DownloadBase:
""" Include latest releases in all views """
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update({
'latest_python2': Release.objects.latest_python2(),
'latest_python3': Release.objects.latest_python3(),
'latest_pymanager': Release.objects.latest_pymanager(),
})
return context

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

latest_pymanager = context.get('latest_pymanager')

python_files = []
for o in OS.objects.all():
data = {
Expand All @@ -80,6 +99,8 @@ def get_context_data(self, **kwargs):
data['python2'] = latest_python2.download_file_for_os(o.slug)
if latest_python3 is not None:
data['python3'] = latest_python3.download_file_for_os(o.slug)
if latest_pymanager is not None:
data['pymanager'] = latest_pymanager.download_file_for_os(o.slug)
python_files.append(data)

context.update({
Expand Down
9 changes: 9 additions & 0 deletions templates/downloads/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,20 @@ <h1 class="call-to-action">Download the latest source release</h1>
{% else %}
<h1 class="call-to-action">Download the latest version for {{ data.os.name }}</h1>
{% endif %}
{% if data.pymanager %}
<p class="download-buttons">
<a class="button" href="{{ data.pymanager.url }}">Download Python install manager</a>
</p>
{% if data.python3 %}
<p>Or get the standalone installer for <a href="{{ data.python3.url }}">{{ data.python3.release.name }}</a></p>
{% endif %}
{% else %}
<p class="download-buttons">
{% if data.python3 %}
<a class="button" href="{{ data.python3.url }}">Download {{ data.python3.release.name }}</a>
{% endif %}
</p>
{% endif %}
</div>
{% endfor %}
<div class="download-unknown">
Expand Down
12 changes: 11 additions & 1 deletion templates/downloads/os_list.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ <h1 class="page-title">Python Releases for {{ os.name }}</h1>
</header>

<ul>
{% if os.slug == 'windows' and latest_pymanager %}
<li><a href="{{ latest_pymanager.get_absolute_url }}">Latest Python install manager - {{ latest_pymanager.name }}</a></li>
{% endif %}

<li><a href="{{ latest_python3.get_absolute_url }}">Latest Python 3 Release - {{ latest_python3.name }}</a></li>
</ul>
<div class="col-row two-col">
Expand All @@ -39,7 +43,13 @@ <h2>Stable Releases</h2>
<li>
<a href="{{ r.get_absolute_url }}">{{ r.name }} - {{ r.release_date|date }}</a>
{% if os.slug == 'windows' %}
{% if r.is_version_at_least_3_9 %}
{% if latest_pymanager and r.is_version_at_least_3_14 %}
{% if latest_pymanager %}
<p>Download using the <a href="{{ latest_pymanager.get_absolute_url }}">Python install manager</a>.</p>
{% else %}
<p>Download using the <a href="https://docs.python.org/using/windows.html">Python install manager</a>.</p>
{% endif %}
{% elif r.is_version_at_least_3_9 %}
<p><strong>Note that {{ r.name }} <em>cannot</em> be used on Windows 7 or earlier.</strong></p>
{% elif r.is_version_at_least_3_5 %}
<p><strong>Note that {{ r.name }} <em>cannot</em> be used on Windows XP or earlier.</strong></p>
Expand Down
6 changes: 6 additions & 0 deletions templates/downloads/supernav.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,16 @@ <h3>Python Source</h3>
{% else %}
<h4>Download for {{ data.os.name }}</h4>
{% endif %}

{% if data.pymanager %}
<p><a class="button" href="{{ data.pymanager.url }}">Python install manager</a></p>
<p>Or get the standalone installer for <a class="button" href="{{ data.python3.url }}">{{ data.python3.release.name }}</a></p>
{% else %}
<p>
<a class="button" href="{{ data.python3.url }}">{{ data.python3.release.name }}</a>
</p>
{% 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 %}
{% endif %}
<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>
</div>
{% endfor %}
Expand Down