Skip to main content

360° health check for Django projects — URLs, forms, admin, models, security, migrations in one command

Project description

django-test-doctor

PyPI License: MIT Python 3.10+ Django 4.2+

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_test_doctor-0.2.1.tar.gz (23.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_test_doctor-0.2.1-py3-none-any.whl (23.8 kB view details)

Uploaded Python 3

File details

Details for the file django_test_doctor-0.2.1.tar.gz.

File metadata

  • Download URL: django_test_doctor-0.2.1.tar.gz
  • Upload date:
  • Size: 23.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for django_test_doctor-0.2.1.tar.gz
Algorithm Hash digest
SHA256 25d9071427b5165816f06dc09fe8a719a2018498e90dba045c8e5f611a9cab2c
MD5 fd3987089a50dee3f96fb7048c43636a
BLAKE2b-256 3f836f29b1147721569fea493bf4b38e97ca541d86426c697559cdc8ba8366c2

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_test_doctor-0.2.1.tar.gz:

Publisher: workflow.yml on Altius-Academy-SNC/django-test-doctor

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file django_test_doctor-0.2.1-py3-none-any.whl.

File metadata

File hashes

Hashes for django_test_doctor-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 5ca695fa3bcb1b24ffdc4bf2a06d076b31adacb0df1f0d2894ea932b4e7cb5a5
MD5 59bf2f254429d9a2d5eb9df0589694fb
BLAKE2b-256 6388042e10a93ec3ed3080f8e65900468fd5e3e878baae82f640f45ed9988a7a

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_test_doctor-0.2.1-py3-none-any.whl:

Publisher: workflow.yml on Altius-Academy-SNC/django-test-doctor

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page