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"]
# tests.py
@pytest.mark.nplus1
class TestMyView:
def test_list_books(self, books):
response = client.get("/books/") # raises NPlus1Error if view has N+1
Tests marked with @pytest.mark.nplus1 will fail if the code under test triggers an N+1 query. Fix the N+1, or use nplus1_allow() in helper functions that intentionally defer prefetching to their callers.
See examples/ for a working project and the docs for full configuration.
Celery Integration
Detect N+1 queries inside Celery tasks, using the same per-execution scoping as the HTTP middleware.
pip install django-nplus1[celery]
# settings.py
NPLUS1_CELERY = True
Each task execution gets its own detection scope. 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 callstask.delay()inside annplus1_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
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_nplus1-0.3.0.tar.gz.
File metadata
- Download URL: django_nplus1-0.3.0.tar.gz
- Upload date:
- Size: 16.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b1ef1a7bfe5ba1fe347b60f23d06df7801238b6b5b9334c486218edd7c39dfbc
|
|
| MD5 |
9e0908a5a748404217ea4f58f19367c2
|
|
| BLAKE2b-256 |
db004c03b35b0423ccfa2e14345702ba253501c42b04cb783466795d578f88a9
|
Provenance
The following attestation bundles were made for django_nplus1-0.3.0.tar.gz:
Publisher:
publish.yml on oliverhaas/django-nplus1
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
django_nplus1-0.3.0.tar.gz -
Subject digest:
b1ef1a7bfe5ba1fe347b60f23d06df7801238b6b5b9334c486218edd7c39dfbc - Sigstore transparency entry: 1293332783
- Sigstore integration time:
-
Permalink:
oliverhaas/django-nplus1@167799cfa3e5b42c1e4647df9b56b0ff04136bc7 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/oliverhaas
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@167799cfa3e5b42c1e4647df9b56b0ff04136bc7 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file django_nplus1-0.3.0-py3-none-any.whl.
File metadata
- Download URL: django_nplus1-0.3.0-py3-none-any.whl
- Upload date:
- Size: 20.2 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 |
9afc22e11b9207087d19d1cfcb155b5630e0dd4358a88478cc8dbe0459583461
|
|
| MD5 |
824aae50b89c2ef2d98a0f90652f73de
|
|
| BLAKE2b-256 |
2df2c91ef53c6cbae2be183256ed263d03cba98de039d7047e213504c980eae0
|
Provenance
The following attestation bundles were made for django_nplus1-0.3.0-py3-none-any.whl:
Publisher:
publish.yml on oliverhaas/django-nplus1
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
django_nplus1-0.3.0-py3-none-any.whl -
Subject digest:
9afc22e11b9207087d19d1cfcb155b5630e0dd4358a88478cc8dbe0459583461 - Sigstore transparency entry: 1293332805
- Sigstore integration time:
-
Permalink:
oliverhaas/django-nplus1@167799cfa3e5b42c1e4647df9b56b0ff04136bc7 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/oliverhaas
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@167799cfa3e5b42c1e4647df9b56b0ff04136bc7 -
Trigger Event:
workflow_dispatch
-
Statement type: