Skip to main content

N+1 query detection for Django

Project description

django-nplus1

N+1 query detection for Django. Beta - API may still change before 1.0.

Quick Start

pip install django-nplus1
# settings.py
INSTALLED_APPS = [..., "django_nplus1"]
# settings/testing.py
MIDDLEWARE = [..., "django_nplus1.NPlus1Middleware"]
NPLUS1_RAISE = True

Adding the middleware to your test settings means every view test that goes through the Django test client will fail on N+1 queries. This catches real problems in actual request paths without false positives from helper functions or scripts that intentionally defer prefetching.

For existing projects, introducing django-nplus1 will likely surface many N+1 queries at once. Whitelist the known issues and fix them over time:

# settings/testing.py
NPLUS1_WHITELIST = [
    {"model": "myapp.Author", "field": "books"},
    {"model": "myapp.Book", "field": "publisher"},
]

The middleware can also run in development or production settings to log warnings instead of raising — see the docs for all options, including the pytest plugin and the Profiler context manager.

See examples/ for a working project.

Celery Integration

The equivalent of the middleware for Celery tasks — each task execution gets its own detection scope.

pip install django-nplus1[celery]
# settings.py (or settings/testing.py)
NPLUS1_CELERY = True

Lazy loads, .get()-in-a-loop, unused eager loads, and duplicate queries are all detected per-task, just as they are per-request. nplus1_allow() works inside tasks the same way it does in views.

Limitations:

  • nplus1_allow() context does not propagate across task boundaries. If a view calls task.delay() inside an nplus1_allow() block, the allow rules do not carry into the worker (ContextVars don't survive serialization).
  • Scope nesting for synchronous subtasks (.apply() inside a task) creates a separate scope for the inner task.

Credits

This project builds on the work of:

  • nplusone by Joshua Carp - the original automatic N+1 detection library for Python ORMs. django-nplus1 started as a Django-specific fork of nplusone's architecture.
  • django-zeal by Tao Bojlen - inspired several features including deferred field detection, .get()-in-a-loop detection, ContextVar-based async safety, call-site tracking, and configurable thresholds.

License

MIT

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_nplus1-0.3.2.tar.gz (16.8 kB view details)

Uploaded Source

Built Distribution

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

django_nplus1-0.3.2-py3-none-any.whl (21.0 kB view details)

Uploaded Python 3

File details

Details for the file django_nplus1-0.3.2.tar.gz.

File metadata

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

File hashes

Hashes for django_nplus1-0.3.2.tar.gz
Algorithm Hash digest
SHA256 1cdab02b9ec6de4a2606695f462e157bce6704e2f19238d802c166ea507aa1f4
MD5 01d6111669458e2f65c9a47559a0c4b5
BLAKE2b-256 f8b8f85bab7d64ca9d17fe109d6671dfcad933b5e19dadca7e15b69b82be2a6a

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_nplus1-0.3.2.tar.gz:

Publisher: publish.yml on oliverhaas/django-nplus1

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_nplus1-0.3.2-py3-none-any.whl.

File metadata

  • Download URL: django_nplus1-0.3.2-py3-none-any.whl
  • Upload date:
  • Size: 21.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for django_nplus1-0.3.2-py3-none-any.whl
Algorithm Hash digest
SHA256 5ce5392d358b13990f600873c283e44819b5bc56c4e466f0afb709b6589ea254
MD5 c717f95d4395881939dd440681046a44
BLAKE2b-256 e53014acea06d08a56f8cfa0d5e9a9e8d3b55d593d5ce5a7894eda2a40b3b165

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_nplus1-0.3.2-py3-none-any.whl:

Publisher: publish.yml on oliverhaas/django-nplus1

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