360° health check for Django projects — URLs, forms, admin, models, security, migrations in one command
Project description
django-test-doctor
360° health check for Django projects. One command, twelve layers of analysis, one verdict.
Installed as django-test-doctor, imported as django_doctor:
pip install django-test-doctor
./manage.py doctor
Why
./manage.py check validates runtime configuration. djlint validates template syntax.
pytest validates whatever you remembered to test. Nothing validates the whole project at once.
Real-world bug that slipped into production despite unit tests:
class ContactPrincipalForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# CRASH — Contact.fonction is a CharField (no choices)
self.fields['fonction'].choices = [('', '---')] + list(self.fields['fonction'].choices)
The view using this form returned HTTP 500 in production. Any ./manage.py doctor run
would have caught it, because the form check instantiates every ModelForm blank.
Layers
| Layer | What it does | Status |
|---|---|---|
system |
Wraps ./manage.py check with rich output |
✅ 0.1 |
urls |
Crawls urlpatterns, probes every URL as anon/user/staff/superuser |
✅ 0.1 |
forms |
Instantiates every Form / ModelForm blank + with empty data |
✅ 0.1 |
migrations |
makemigrations --check --dry-run, detects missing migrations |
✅ 0.1 |
admin |
list_display / list_filter / search_fields fields actually exist |
✅ 0.2 |
models |
__str__ defined, Meta.ordering, FK on_delete=SET_NULL with null=False |
✅ 0.2 |
security |
check --deploy + forbidden SECRET_KEY substrings + DEBUG=True |
✅ 0.2 |
templates |
{% url %}, {% static %}, context vars vs get_context_data |
🚧 0.3 |
views |
Permission declared, LoginRequired, has a test (via coverage) |
🚧 0.3 |
drf |
Serializer ↔ model fields match, OpenAPI diff vs HEAD~1 for breaking |
🚧 0.4 |
static |
Every {% static "x" %} resolves to a file that exists |
🚧 0.4 |
i18n |
Untranslated msgid, stale .mo vs .po, missing _() wrapping |
🚧 0.4 |
Quickstart
pip install django-test-doctor
Add to INSTALLED_APPS:
INSTALLED_APPS = [
...,
"django_doctor",
]
Then:
./manage.py doctor # full report
./manage.py doctor --section forms,urls # target specific layers
./manage.py doctor --quick # skip slow layers
./manage.py doctor --ci # exit 1 on critical/error
./manage.py doctor --html report.html # browsable report
./manage.py doctor --diff origin/main # only re-check what changed
./manage.py doctor --fix # auto-fix (run makemigrations, compilemessages)
./manage.py doctor --watch # dev mode, re-run on save
Configuration
In your project's pyproject.toml:
[tool.django-doctor]
enabled = ["*"]
disabled = ["drf"]
fail_on = ["critical", "error"]
ignore = ["urls:admin:*", "forms:legacy_migrations.*"]
[tool.django-doctor.urls]
roles = ["anonymous", "staff"]
skip = ["admin:*"]
timeout = 10
Plugin API
Third-party checks plug in via the django_doctor.checks entry point:
[project.entry-points."django_doctor.checks"]
my_check = "my_package.checks:MyCheck"
# my_package/checks.py
# note: imports use django_doctor — the distribution is django-test-doctor
from django_doctor import Check, Finding, Severity
class MyCheck(Check):
id = "my_check"
description = "Verify my custom invariant"
def run(self, project):
for thing in project.iter_something():
if not thing.ok:
yield Finding(
severity=Severity.ERROR,
location=thing.file_path,
message=f"{thing!r} is broken",
fix_hint="Run ./manage.py fix_things",
)
Status
Alpha — 0.2 ships seven layers (system / urls / forms / migrations / admin / models /
security). Roadmap in CHANGELOG.md.
License
MIT © Paul Guindo
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file django_test_doctor-0.2.2.tar.gz.
File metadata
- Download URL: django_test_doctor-0.2.2.tar.gz
- Upload date:
- Size: 24.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0265156a043b8c935afe372a0bc485e864d8b4c52eb93073e929ba7fe10034e4
|
|
| MD5 |
f94ec79660f776c17ff5329b046f8ce1
|
|
| BLAKE2b-256 |
ca871031ca57842b50eae76609956a39a539ae82feba2809817f1c00458bbc5c
|
Provenance
The following attestation bundles were made for django_test_doctor-0.2.2.tar.gz:
Publisher:
workflow.yml on Altius-Academy-SNC/django-test-doctor
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
django_test_doctor-0.2.2.tar.gz -
Subject digest:
0265156a043b8c935afe372a0bc485e864d8b4c52eb93073e929ba7fe10034e4 - Sigstore transparency entry: 1342568992
- Sigstore integration time:
-
Permalink:
Altius-Academy-SNC/django-test-doctor@bd0c9aed88507eceeb16128e24b6d0d6181f03aa -
Branch / Tag:
refs/tags/v0.2.2 - Owner: https://github.com/Altius-Academy-SNC
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@bd0c9aed88507eceeb16128e24b6d0d6181f03aa -
Trigger Event:
release
-
Statement type:
File details
Details for the file django_test_doctor-0.2.2-py3-none-any.whl.
File metadata
- Download URL: django_test_doctor-0.2.2-py3-none-any.whl
- Upload date:
- Size: 24.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1369fc0e902a3562dc6c637f6e3d0f8430b86dc1e9cbea156ade1f4ff2c08da0
|
|
| MD5 |
e5ec23500ecee1c5cabefc28a617e3a7
|
|
| BLAKE2b-256 |
6819f7533ea77df95e02755fb0e01a5d8d26cf1439f78b1fb16ebdddfeda8f55
|
Provenance
The following attestation bundles were made for django_test_doctor-0.2.2-py3-none-any.whl:
Publisher:
workflow.yml on Altius-Academy-SNC/django-test-doctor
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
django_test_doctor-0.2.2-py3-none-any.whl -
Subject digest:
1369fc0e902a3562dc6c637f6e3d0f8430b86dc1e9cbea156ade1f4ff2c08da0 - Sigstore transparency entry: 1342568995
- Sigstore integration time:
-
Permalink:
Altius-Academy-SNC/django-test-doctor@bd0c9aed88507eceeb16128e24b6d0d6181f03aa -
Branch / Tag:
refs/tags/v0.2.2 - Owner: https://github.com/Altius-Academy-SNC
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@bd0c9aed88507eceeb16128e24b6d0d6181f03aa -
Trigger Event:
release
-
Statement type: