Skip to main content

django-nplus1

N+1 query detection for Django. The API is in beta and can 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.

Corpus Mode

Per-request unused_eager_load detection can produce false positives on shared prefetch patterns. Corpus mode collects eager loads across the full pytest session and only reports the ones no test read:

uv run pytest --nplus1-eager-corpus

It also reports concrete fields that were loaded but never read across the suite, as unused_field_load. Suppress noisy models with NPLUS1_FIELD_EXCLUDE = ["auth.User", "contenttypes.*"].

See docs for suppression markers and pytest-xdist support.

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 and unused eager loads are detected per task, just as they are per request, and so are duplicate queries when NPLUS1_DETECT_DUPLICATE_QUERIES is on. 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).
  • A detection made when a task ends, such as an unused eager load, or one that the task catches, can't fail the task, because Celery has already recorded its result. It is logged at ERROR level on the django_nplus1 logger instead. For a task run with .apply() inside another scope, such as a request or the nplus1 test fixture, that scope reports the detection when it ends.
  • With NPLUS1_RAISE, a detection fails the task, and a task with autoretry_for=(Exception,) is retried for it.

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, which inspired several features: deferred field detection, .get()-in-a-loop detection, ContextVar-based async safety, call-site tracking, and configurable thresholds.

License

MIT

Metadata

Release files for django-nplus1 0.6.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-nplus1 0.6.0
File Size Uploaded
django_nplus1-0.6.0.tar.gz 28.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-nplus1 0.6.0
File Interpreter ABI Platform
django_nplus1-0.6.0-py3-none-any.whl Python 3 none any Details

Total release size: 63.4 kB

Release files / django_nplus1-0.6.0.tar.gz

Download URL django_nplus1-0.6.0.tar.gz
Size 28.5 kB
Tags Source
SHA-256 checksum
How to use checksums
8f526ddc3ec59cc489752fc1a0b859dc33bb3a1cd31dafba310fb0b254586580
BLAKE2b-256 checksum
How to use checksums
ca9c3ec0a8c70ab830d7ff2258c41c62df2b067a90b13fc930b605d7f2e70f56
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.

Transparency log

Release files / django_nplus1-0.6.0-py3-none-any.whl

Download URL django_nplus1-0.6.0-py3-none-any.whl
Size 34.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cd9ad7115dff7268986574954860d6523c41ca874bd7a243504963f957b8493a
BLAKE2b-256 checksum
How to use checksums
8912d305350300d072e22b5e865ba14a46b6522ef47baf03fe3f6c965b8a172d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.

Transparency log

Release history Release notifications | RSS feed

0.6.2

2 release files

0.6.1

2 release files

This release

0.6.0 This release

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page