D3.1 phase 5: Rename CustomUser to User (RenameModel, AUTH_USER_MODEL)
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 48/100
Research direction
Confirm dependency #393, then read the current account model, migration history, settings, and accounts/identity_inventory.py, including the listed literal values. Run make django-check, make migrations-check, and the focused identity tests before the full suite and browser checks. Done means the rename preserves rows, resolves accounts.User with accounts_user, fixes import and literal fallout, and satisfies the stated grep and migration checks.
Written by the indexing model from the issue text.
Description
Part of the D3.1 umbrella (#334): phase 5 of 6. P7 step 2's model rename, isolated as its own small, final-schema-shape step.
Normative sources
| Source | What it governs |
|---|---|
community-base repo: docs/03-playbooks.md P7 DTC step 2 |
Rename procedure |
| #334, owner decision comment (2026-09-08) | Confirms the AUTH_USER_MODEL setting-value change ships in the same deployable unit as the rename; only the rest of P7 step 5 (the get_user_model() idiom sweep, django_migrations cleanup) stays deferred |
| #334, grooming supplement comment (2026-09-08) | The accounts/identity_inventory.py string-literal fallout this issue must fix |
Goal
migrations.RenameModel("CustomUser", "User") and AlterModelTable to accounts_user, AUTH_USER_MODEL updated to "accounts.User" in the same change. End state: model accounts.User, table accounts_user, all rows preserved, zero behavior change.
Scope
- The rename migration, using the operation sequence
makemigrationsgenerates. AUTH_USER_MODEL = "accounts.User"in settings, landed atomically with the migration (Django cannot resolve the old model name after the rename — see the linked owner decision).- Fix every now-broken
CustomUserimport across the codebase. accounts/identity_inventory.pyliteral fixes (do not skip — these live in string literals, so neither the import rewrite nor an attribute-access grep catches them):ACCOUNT_MANY_TO_MANY_RELATIONS:"owner_model": "accounts.CustomUser", the"through_table"valuesaccounts_customuser_groups/accounts_customuser_user_permissions(implicit m2m through tables rename with the model),"user_field": "customuser"(the reverse accessor becomesuser).ACCOUNT_RELATIONS's first entries:"accounts.CustomUser_groups"/"customuser".- By contrast,
accounts_customuserliterals inaccounts/services/cmp_learner_import.pyandCmpLearnerImportProgress.tablevalues name the CMP export's source tables, not the live table, and must NOT be touched.
- Verify current
mainfor any furtherCustomUser-literal oraccounts.CustomUsermodel-label string added since #334's original grooming (for example inaccounts/tests/test_identity_quarantine_revocation.py,accounts/tests/test_username_allocation.py, and themanagement_auth/management_apimodules touched by that same BE-08 fix) before finishing — this table is a floor, not the full inventory.
Non-goals
- No
get_user_model()idiom sweep beyond fixing imports the rename itself breaks. - No
django_migrationscleanup, no squashed-migration--fake, noP5relabel work. - No AISL field additions (phase 6).
- No login-behavior, allauth-adapter, or permission-logic change beyond rename fallout.
Dependencies
- Depends on: #393 (the contract phase must land first — renaming while stale duplicate fields still exist on
CustomUserrisks the rename migration and the field-removal migration racing on the same table during a rebase). - Blocks:
D3.2andC3.7(per #334), and #395 (kept last to match the original plan's stated ordering; phase 6 is otherwise independent and could reorder if the owner prefers).
Acceptance criteria
Django and integration
-
make django-check/make migrations-checkpass. -
make test(full suite) passes. -
get_user_model()resolves toaccounts.Userwithdb_tableaccounts_user. - Email login authenticates through the Django test client (login, session, member page 200); the dark-mode toggle endpoint still works end to end through
learner_profile. -
grep -rn "CustomUser\|accounts_customuser" --include=*.py . | grep -v migrations | grep -v .tmpshows only the CMP-import source-table literals and any deliberately preserved docstring/comment references; the PR body records this grep's output. -
manage.py migrateapplies cleanly end to end on a fresh database.
Browser
-
make test-playwright-corepasses. - [HUMAN] After the development deploy: login with an existing development account works and the dark-mode toggle persists.
Repository and operations
- Versioned verification plan per
_docs/ci/change-selective-ci.mdrecorded in the engineer handoff.
- Dominant language
- Python
- Stars
- 0
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Getting set up
- Ships a Dockerfile or Docker Compose file
- No pull request template
- No contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from DataTalksClub/website
-
bug infra operations P1 testing
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
DataTalksClub/website#329 ·
-
bug content data-migration documentation events operations P1
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
DataTalksClub/website#327 ·
-
bug frontend P0 testing
Difficulty 2/5 1-3 hours Newbie friendliness 90/100
DataTalksClub/website#300 · 7 comments ·
-
bug data-migration events P0 testing
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
DataTalksClub/website#295 · 6 comments ·
-
courses enhancement P2
Difficulty 4/5 3-5 days Newbie friendliness 35/100
DataTalksClub/website#455 · 6 comments ·
All issues in DataTalksClub/website
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Juniper/ansible-junos-stdlib#904 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
pollen-robotics/reachy_mini#1457 ·
Maintainers usually reply within 1 day
-
area:runtime good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
WATonomous/wato_f1tenth#39 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
FireDynamics/fdsreader#123 ·
-
Difficulty 1/5 Under an hour Newbie friendliness 85/100