Django N+1¶
Beta
This package is under active development and the API may change before 1.0.
N+1 query detection for Django.
Based on nplusone by Joshua Carp, a well-established library for automatic N+1 detection across Python ORMs. If you need broad ORM support (SQLAlchemy, Peewee, etc.), nplusone is still the best choice.
Several features (deferred field detection, call-site tracking, .get()-in-a-loop detection, ContextVar-based async safety, and configurable thresholds) were inspired by django-zeal by Tao Bojlen.
django-nplus1 is a Django-only fork that drops legacy compatibility in favour of Python 3.14+ / Django 6+, uses a ContextVar-based signal system, and adds unused eager-load detection.
Features¶
- N+1 detection: Warns when a related object is lazily loaded on an instance that was part of a bulk query
- Deferred field detection: Detects N+1 from
.defer()/.only()field access .get()in a loop detection: DetectsModel.objects.get()called repeatedly from the same call-site- Unused eager load detection: Warns when
select_relatedorprefetch_relatedresults are never accessed - Call-site tracking: Error messages include the exact file, line number, and function name
- Async support: Works with both sync and async Django views
- Middleware: Automatically monitors all requests (sync and async)
- Celery integration: Per-task detection via
task_prerun/task_postrunsignals - pytest plugin:
nplus1fixture and@pytest.mark.nplus1marker for test-time detection - Profiler: Context manager for manual use in scripts or tests
- Whitelisting: Ignore specific model/field combinations with wildcard support and typo detection
- Inline suppression:
# nplus1: ignorecomments for per-line suppression nplus1_allow(): Context manager to locally suppress detection for specific code blocks- Multiple notification methods: Logging, exceptions,
warnings.warn_explicit(), and a Django signal - Duplicate query detection: Optional SQL-level fallback catches N+1 from raw SQL and
.raw() - Configurable threshold:
NPLUS1_THRESHOLDcontrols detection sensitivity - Zero dependencies: Only requires Django
Quick Start¶
INSTALLED_APPS = [
...,
"django_nplus1",
]
MIDDLEWARE = [
...,
"django_nplus1.NPlus1Middleware",
]
# Recommended for test settings
NPLUS1_RAISE = True
Requirements¶
- Python 3.14+
- Django 6+