AlexsLemonade / AlexsLemonade/refinebio
Upgrade to Django 5.2
- Dominant language
- Python
- Stars
- 135
- Forks
- 21
- PR merge metrics
- No merged PRs in 30d
Description
# Upgrade Django to 5.2 LTS
## Goal
Move every `requirements.in` from `django>=3.2,<4` to `django>=5.2,<5.3` (LTS, supported through April 2028). Bump `djangorestframework` past the `<3.14.0` cap. Audit and bump every other Django ecosystem package to a version that supports Django 5.x. Land the result on the upgraded Python baseline (3.10+) that the image upgrade provides.
## Prerequisite
Land the Ubuntu 18.04 upgrade first (see `upgrade-base-image-from-ubuntu-18.md`). Django 5.x requires Python 3.10 or newer; we are on Python 3.8 today, which Django 5.x will not run on. Do not start this until `Dockerfile.base` is on Python 3.10+ and CI is green against the new image.
## Why
- Django 3.2 LTS extended support ended April 2024. We are running on an unsupported branch.
- Several pins exist solely because of the 3.2 lock: `djangorestframework<3.14.0`, `django-elasticsearch-dsl==6.5.0`, `django-elasticsearch-dsl-drf>=0.17.1`. Cleaning these up is gated on Django moving forward.
- Django 5.2 is an LTS and gives us a three-year runway. Skipping to 5.2 (rather than stepping through 4.2 first) is acceptable for a project with this much in-house code, but the migration plan should still walk the changelogs to catch removals.
## Current state
- `common/data_refinery_common/settings.py` is the single shared settings module. `USE_L10N = True` is set (line 126) and `DEFAULT_AUTO_FIELD = "django.db.models.AutoField"` is set (line 18).
- Django is pinned `>=3.2,<4` in five `requirements.in` files: `common/`, `foreman/`, `api/`, `workers/data_refinery_workers/processors/`, `workers/data_refinery_workers/downloaders/`.
- Resolved versions today: `django==3.2.17` / `3.2.18`, `djangorestframework==3.13.1`, `django-computedfields==0.2.1`, `django-elasticsearch-dsl==6.5.0`, `django-elasticsearch-dsl-drf==0.22.5`, `django-cors-headers==3.13.0`, `django-filter==22.1`, `django-fast-update==0.2.1`, `django-nine==0.2.7`, `djangorestframework-hstore==1.3`, `psycopg2-binary==2.9.5`.
## Breakage surface to walk
Step through each major's release notes and harvest deprecations / removals before bumping. The non-exhaustive list of things known to affect this codebase:
### 3.2 -> 4.0
- `USE_L10N` deprecated. Remove from `common/data_refinery_common/settings.py:126`.
- `default_app_config` removal in app configs.
- Several `django.utils.encoding` helpers removed.
### 4.0 -> 4.1
- `Form.is_valid()` async paths.
- `assertFormError` / `assertFormsetError` signature change.
### 4.1 -> 4.2
- `psycopg3` support added alongside `psycopg2`. We do not need to switch but should evaluate whether `psycopg[binary]>=3` is worth adopting; if so, change the pin and audit raw cursor usage.
- `STORAGES` setting introduced; the old `DEFAULT_FILE_STORAGE` / `STATICFILES_STORAGE` keys deprecated.
### 4.2 -> 5.0
- `USE_L10N` removed entirely. Settings must not contain it.
- Model field `choices` now accepts a `Choices` enum directly (informational).
- Async auth backends supported.
### 5.0 -> 5.1
- PostgreSQL 13+ required. Verify the prod RDS version is 13 or newer before this lands.
- `LoginRequiredMiddleware` introduced.
### 5.1 -> 5.2
- `HttpResponse.text` attribute added.
- Composite primary keys (preview only, irrelevant unless we opt in).
## Third-party compatibility audit
The single biggest unknown. Each of these is currently pinned at a version that almost certainly does not support Django 5.x and needs an upgrade or replacement:
| Package | Current | Concern |
|---|---|---|
| `djangorestframework` | 3.13.1 (capped `<3.14.0`) | DRF 3.15+ supports Django 5.x. Drop the cap. |
| `django-elasticsearch-dsl` | 6.5.0 | Pinned because we run Elasticsearch 6.8 (`elasticsearch==6.8.2`). Upgrading Django may force an ES upgrade. Big.|
| `django-elasticsearch-dsl-drf` | 0.22.5 | Same ES coupling. Upstream activity is low; may need a fork or migration to a different search package. |
| `django-computedfields` | 0.2.1 | Check whether current releases support 5.x. |
| `django-cors-headers` | 3.13.0 | 4.x supports Django 5. |
| `django-filter` | 22.1 | 23.x+ supports Django 5. |
| `djangorestframework-hstore` | 1.3 | Niche package. Confirm activity; if stale, evaluate whether `JSONField` can replace it. |
| `drf-yasg` | (transitive) | Maintained but slow. `drf-spectacular` is the modern alternative for OpenAPI 3. |
| `django-fast-update` | 0.2.1 | Transitive via `django-computedfields`. Will follow whatever that one needs. |
| `django-nine` | 0.2.7 | Transitive via `django-elasticsearch-dsl-drf`. Will follow that decision. |
The Elasticsearch DSL situation deserves its own analysis paragraph in the implementation PR: it may be that the cleanest path is to bump the entire ES stack (server, client, DSL) at the same time as Django, since the version coupling is tight.
## Scope of changes
- All five `requirements.in` files bumped to `django>=5.2,<5.3`.
- `djangorestframework<3.14.0` cap removed; pin to a Django 5.x-compatible release.
- Each row in the third-party table resolved to a specific target version or replacement.
- `requirements.txt` files regenerated.
- `common/data_refinery_common/settings.py`: `USE_L10N` removed; verify `TEMPLATES`, `DATABASES`, and middleware blocks still match current Django shape.
- Run `manage.py check --deploy` and `manage.py makemigrations --check --dry-run` against every project (`common`, `foreman`, `api`, workers) and resolve everything it complains about.
- Walk `git grep` for deprecated APIs surfaced by 4.x / 5.x release notes; the non-exhaustive list includes `default_app_config`, `USE_L10N`, anything from `django.utils.encoding` that was removed, and the `STORAGES` migration if we touch file storage settings.
## Risks
- Elasticsearch DSL coupling could force an ES server-side upgrade. This is the highest-risk item in the entire upgrade and may justify pulling it into its own follow-up issue rather than bundling.
- Third-party packages without active maintenance (`django-nine`, possibly `djangorestframework-hstore`) may not have Django 5-compatible releases. Replacement or vendoring may be required.
- We have a large number of existing migrations (`common/data_refinery_common/migrations/`). Django 5 should run them, but a `makemigrations --check` against a 5.x install will surface any drift.
- Three years of cumulative deprecation warnings can hide behavior changes that only surface at runtime. Plan time for an integration soak rather than relying purely on the test suite.
## Acceptance criteria
- [ ] All five `requirements.in` files pinned to `django>=5.2,<5.3`.
- [ ] No `<3.14.0` cap remains on `djangorestframework` (or whichever upper bounds existed solely because of Django 3.2).
- [ ] Every Django ecosystem package resolves to a version that explicitly supports Django 5.x.
- [ ] `USE_L10N` removed from `common/data_refinery_common/settings.py`.
- [ ] `manage.py check` passes for `common`, `foreman`, `api`.
- [ ] `manage.py makemigrations --check --dry-run` reports no pending migrations.
- [ ] Full test suite passes against the new image: `bin/rbio test:common`, `test:foreman`, `test:api`, `test:workers`.
- [ ] Production RDS Postgres version confirmed at 13 or newer (Django 5.1+ requirement).
- [ ] Search functionality validated end-to-end on the new Django + Elasticsearch combination.
## Suggested sequencing
1. Confirm the prerequisite: `Dockerfile.base` is on Python 3.10+ and CI is green.
2. Decide upfront whether the Elasticsearch DSL upgrade rides with this issue or splits out. If it splits, this issue is blocked on the ES upgrade landing first.
3. Land the bump as one focused PR: `requirements.in` changes, regenerated `requirements.txt`, `USE_L10N` removed, any other deprecated settings cleaned up.
4. Follow-up PRs as needed for any specific package replacements (e.g. `drf-yasg` -> `drf-spectacular`).
## References
- `common/data_refinery_common/settings.py` (shared Django settings)
- `common/requirements.in`, `foreman/requirements.in`, `api/requirements.in`, `workers/data_refinery_workers/processors/requirements.in`, `workers/data_refinery_workers/downloaders/requirements.in`
- Django 4.0, 4.1, 4.2, 5.0, 5.1, 5.2 release notes
- Related upgrade work: `.workspace/upgrade-base-image-from-ubuntu-18.md`
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.