models & migrations¶
Two data-layer hygiene checks. models is pure introspection;
migrations delegates to ./manage.py makemigrations --check --dry-run
for byte-for-byte parity with the CLI verdict.
models¶
For every first-party, non-abstract model, checks:
__str__— ifModel.__str__ is models.Model.__str__(i.e. not overridden), emit WARNING. The default repr (<MyModel: object (42)>) makes admin / shell / logs painful.Meta.ordering— absent → INFO (WARNING if listed insoft_checks). Pagination becomes DB-order-dependent.on_delete=SET_NULLon aNOT NULLFK — ERROR. Silent time-bomb: works until the first parent deletion, thenIntegrityError.
Tuning¶
[tool.django-doctor.models]
skip_apps = ["admin", "auth", "contenttypes", "sessions", "messages", "sites"]
soft_checks = ["ordering_missing"] # emit WARNING instead of INFO
migrations¶
Calls call_command("makemigrations", dry_run=True, check_changes=False)
in-process, captures stdout, and parses Migrations for 'app': lines.
Byte-for-byte parity with ./manage.py makemigrations --check --dry-run.
Why not reimplement MigrationAutodetector directly? Because the
makemigrations command carries subtle defaults (the questioner, app
trimming, consistency checks) that diverge from a raw autodetector call.
Earlier releases did — 0.2.1 reported phantom AlterField drift on
up-to-date projects. 0.2.2 fixed it by delegating.
Also reports migrations.unapplied when the migration graph has leaves
that aren't applied to DEFAULT_DB_ALIAS.
Why only first-party apps¶
By default migrations skips everything whose app source lives in
site-packages/ or dist-packages/. Users can't fix drift in third-party
packages anyway — it's noise. Flip to reports-everything with: