Skip to content

Django Upgrade Phase 4 — Django 3.2 → 4.2 LTS (Python 3.12) - #1574

Open
viniciusandrade wants to merge 2 commits into
mainfrom
setup/django-4.2
Open

Django Upgrade Phase 4 — Django 3.2 → 4.2 LTS (Python 3.12)#1574
viniciusandrade wants to merge 2 commits into
mainfrom
setup/django-4.2

Conversation

@viniciusandrade

Copy link
Copy Markdown
Member

Phase 4 of the staged Django upgrade: Django 3.2.25 → 4.2.30 LTS on Python 3.12.

Goals

  • Django 3.2.25 → 4.2.30 LTS with Python 3.10 → 3.12 (python:3.12-alpine)
  • Bump Django-pinned outliers: jsonfield 3.1.0 → 3.2.0, django-rosetta 0.9.9 → 0.10.3
  • Remove USE_L10N and the dead TEMPLATE_DEBUG from settings (after the bump)
  • Full test suite passes in the rebuilt Python 3.12 image — 223 tests, 13 apps, all OK
  • JSONField behavior unchanged after the jsonfield bump (biblioref/oer/leisref green)
  • Remaining Django 5.x deprecation warnings logged for Phase 5
  • make dev_migrate runs clean — blocked, see caveat below

Changes

Dependencies / runtime

  • Django==4.2.30, jsonfield==3.2.0, django-rosetta==0.10.3
  • Dockerfile base image → python:3.12-alpine

DeleteView conversions (Django 4.0 breakage)
Django 4.0 made DeleteView form-based, so delete() overrides are no longer called. Eight views converted to form_valid() across biblioref, title, institution, leisref, multimedia, oer, thesaurus.

This also closes a real data-loss path: the old overrides called super().get_object(), deliberately bypassing each view's own authorization hook — so on an unauthorized POST, the related-object cleanup deletes ran first and the request only failed afterwards. self.object now comes from the overridden get_object(), so unauthorized requests fail before any delete.

thesaurus DescDeleteView/QualifDeleteView additionally pin form_class = Form and drop the inherited ths form kwarg, since they inherit from update views.

Settings

  • USE_L10N removed (deprecated in 4.0), dead TEMPLATE_DEBUG removed from both settings.py and settings_local.py-SAMPLE

Tooling / tests

  • New make dev_test_deprecations target (python -Wd) for Phase 5 warning triage
  • Three new biblioref tests covering the converted delete views

⚠️ Caveat: make dev_migrate unverified

The dev/test database is MariaDB 10.3.34 and Django 4.2 requires ≥ 10.4, so it refuses to connect. This is an infrastructure blocker, not a code defect. Substituted checks: all migrations apply cleanly on SQLite under 4.2, and makemigrations output diffed between 3.2 and 4.2 on identical code shows exactly one new detected change (title.users hidden related_name, metadata-only, no schema impact); the ~100 other pending AlterFields are pre-existing drift, byte-identical under 3.2.

Real-DB verification stays deferred to the validation environment, consistent with the spec's accepted SQLite-only gap.

Follow-ups worth queuing

  • Upgrade the dev MariaDB past 10.4
  • The 5 biblioref tests still behind @skip("Figure out why these tests are broken!") — that skip is why the delete regression went unnoticed
  • Pre-existing warts left untouched: MediaDeleteView/OERDeleteView return HttpResponse(401) instead of raising (500 rather than a clean 401); thesaurus get_success_url() raises TypeError when ths is absent

Implementation log: .ai/logs/2026-08-27-upgrade-django-4.2.md

🤖 Generated with Claude Code

https://claude.ai/code/session_018vQdjRN1v24o6subxb8BvQ

- Django 3.2.25 -> 4.2.30, base image python:3.10-alpine -> python:3.12-alpine
- jsonfield 3.1.0 -> 3.2.0, django-rosetta 0.9.9 -> 0.10.3
- Convert eight DeleteView.delete() overrides to form_valid(), required by
  the form-based DeleteView introduced in Django 4.0. This also fixes a
  data-loss path: the old code used super().get_object(), bypassing each
  view's authorization hook, so related-object cleanup ran before the
  request was rejected.
- thesaurus DescDeleteView/QualifDeleteView: pin form_class = Form and drop
  the inherited `ths` form kwarg so deletion actually runs
- Remove USE_L10N (deprecated in 4.0) and the dead TEMPLATE_DEBUG from
  settings.py and settings_local.py-SAMPLE
- Add `make dev_test_deprecations` (python -Wd) for Phase 5 warning triage
- Add three biblioref delete-view tests covering the converted code

223 tests pass on Python 3.12 / Django 4.2. `make dev_migrate` against the
real DB is unverified: the dev MariaDB is 10.3.34 and Django 4.2 requires
>= 10.4.
Django 4.0+ defaults SECURE_CROSS_ORIGIN_OPENER_POLICY to 'same-origin', so
SecurityMiddleware started sending Cross-Origin-Opener-Policy: same-origin after
the Django 4.2 upgrade. That severs window.opener for cross-origin popups, and
the DeCS locator window opened by decs_search() failed with "Cannot read
properties of null (reading 'postMessage')".

Set the policy to 'same-origin-allow-popups' so popups opened by fi-admin can
still post the selected descriptor back.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant