Upgrades Django 5.2.18 → 6.1.2 and Python 3.11.14 → 3.12.16. No tracking issue existed for this, so this PR is the record.
Rebased onto current main. The earlier stack layer this sat on (#114, mise) is merged, and this PR now targets main directly.
IMPORTANT
Blocked by #143 — the host has to be on PostgreSQL 15+ before this can deploy. Django 6.1 refuses to connect to 14.
Python 3.12 is a prerequisite, not a preference
Django 6.0 dropped support for Python older than 3.12, so 5.2.x is the last line that runs on 3.11. The interpreter bump is unavoidable if we want latest.
3.12.16 is the newest patch in the line, from the 25 October 2026 security release — the branch originally pinned 3.12.9, and there is no reason to ship a stale patch when the security fixes are free.
3.12 specifically, not 3.13+: py-cord is pinned ~=2.6.0, and py-cord 2.6 imports audioop, which Python 3.13 removed from the stdlib. Moving to 3.13 would break the Discord bot until that pin moves. 3.12 is the smallest bump that gets us there.
Also adds [requires] python_version to the Pipfile — without it pipenv resolves the newest interpreter on PATH instead of the one .python-version names, which silently built the virtualenv on 3.14 the first time around. (#114 independently fixes the same class of bug by passing pipenv an explicit --python; the two are belt and braces, and the Pipfile entry is also what pipenv itself validates against.)
Django 6.1 raises the database floor to PostgreSQL 15
This is the part that needs attention before deploy. Django 6.1 refuses to connect to PostgreSQL 14 or older, and our dev setup was pinned to 14 — so the upgrade as originally written could not pass CI. This PR now also:
- installs PostgreSQL 15 for the embedded dev database
- stops with an explanation when
DEV_PGDATApoints at a cluster from another major version, instead of letting PostgreSQL fail withdatabase files are incompatible with server(existing dev machines have a 14 cluster and will hit this) - updates the README and
.env.exampleversion references
Deploy host: apt install postgresql on a current Debian already gives 15 or newer, so a recently provisioned host is fine. A host still on 14 needs a pg_upgrade (or dump-and-restore) before this ships.
Dependency changes
| Package | Change | Why |
|---|---|---|
django | ~=5.2.17 → ~=6.1.2 | the point of the PR |
django-computedfields | ~=0.2.6 → ~=0.3.6 | 0.2.x caps at Django<6.0 — the only hard blocker |
django-computedfields 0.3.x lists no breaking changes; the one change marked BREAKING in the 0.2.10→0.3.6 range landed in 0.2.10, which we were already running. Our only computed field is Payment.is_successful, self-dependent and not an FK or m2m field, so none of the 0.3.x behavior changes apply.
⚠️ 0.3.6 declares Django 6.0 support, not 6.1 (its pin is Django<7.0,>=5.0), so we are one minor ahead of what upstream tests. Worth watching their next release.
Relocking also floated the unpinned packages: fastapi 0.143 → 0.162, starlette 1.8 → 1.10, sentry-sdk 2.72 → 2.73, css-inline 0.22 → 0.23, plus patch bumps elsewhere. All within their declared ranges, and the suite covers the paths we use.
Verification
On Python 3.12.16 / Django 6.1.2 / PostgreSQL 15, against current main:
manage.py checkclean;makemigrations --checkreports no changes- 188 tests pass
ruff checkandruff format --checkclean (90 files)mypyclean across 187 filesmanage.py checkdata: 0 desyncedPayment.is_successfulrecords- CI green
The upgrade itself was also deployed for real onto a throwaway Ubuntu 24.04 host earlier in this branch's life (nginx, system postgresql, virtualenv on 3.11): ./deploy/run.sh exited 0, logged Virtualenv is on Python 3.11 but 3.12 is required; recreating it., and afterwards gunicorn.socket, gunicorn.service, both mail timers and nginx were active, with /accounts/login/ 200 and /admin/ 302. The only change since is the patch bumps and the PostgreSQL 15 floor noted above.
Activity
6This pull request is a draft
Merging is unavailable until it is marked ready for review.