Django Upgrade Phase 4 — Django 3.2 → 4.2 LTS (Python 3.12) - #1574
Open
viniciusandrade wants to merge 2 commits into
Open
Django Upgrade Phase 4 — Django 3.2 → 4.2 LTS (Python 3.12)#1574viniciusandrade wants to merge 2 commits into
viniciusandrade wants to merge 2 commits into
Conversation
- 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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase 4 of the staged Django upgrade: Django 3.2.25 → 4.2.30 LTS on Python 3.12.
Goals
python:3.12-alpine)jsonfield3.1.0 → 3.2.0,django-rosetta0.9.9 → 0.10.3USE_L10Nand the deadTEMPLATE_DEBUGfrom settings (after the bump)make dev_migrateruns clean — blocked, see caveat belowChanges
Dependencies / runtime
Django==4.2.30,jsonfield==3.2.0,django-rosetta==0.10.3python:3.12-alpineDeleteView conversions (Django 4.0 breakage)
Django 4.0 made
DeleteViewform-based, sodelete()overrides are no longer called. Eight views converted toform_valid()acrossbiblioref,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.objectnow comes from the overriddenget_object(), so unauthorized requests fail before any delete.thesaurusDescDeleteView/QualifDeleteViewadditionally pinform_class = Formand drop the inheritedthsform kwarg, since they inherit from update views.Settings
USE_L10Nremoved (deprecated in 4.0), deadTEMPLATE_DEBUGremoved from bothsettings.pyandsettings_local.py-SAMPLETooling / tests
make dev_test_deprecationstarget (python -Wd) for Phase 5 warning triagebiblioreftests covering the converted delete viewsmake dev_migrateunverifiedThe 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
makemigrationsoutput diffed between 3.2 and 4.2 on identical code shows exactly one new detected change (title.usershiddenrelated_name, metadata-only, no schema impact); the ~100 other pendingAlterFields 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
biblioreftests still behind@skip("Figure out why these tests are broken!")— that skip is why the delete regression went unnoticedMediaDeleteView/OERDeleteViewreturnHttpResponse(401)instead of raising (500 rather than a clean 401);thesaurusget_success_url()raisesTypeErrorwhenthsis absentImplementation log:
.ai/logs/2026-08-27-upgrade-django-4.2.md🤖 Generated with Claude Code
https://claude.ai/code/session_018vQdjRN1v24o6subxb8BvQ