Changelog¶
0.3.0¶
- Inline
# nplus1: ignoresuppression. Add a trailing comment to the call site to suppress a detection, optionally scoped to labels (# nplus1: ignore[n_plus_one, get_in_loop]). - Fix false positive on
qs.prefetch_related(...).filter(pk=X)where a queryset-level prefetch returning a single instance was flagged as N+1.
0.2.0¶
- Celery integration: per-task N+1 detection via
task_prerun/task_postrunsignals. Enable withNPLUS1_CELERY = Trueorpip install django-nplus1[celery]. - Extract
DetectionContextas a reusable public class for scoped detection. - Require Python 3.14+ and Django 6+.
0.1.0¶
Initial release.
- N+1 lazy load detection for related fields (ForeignKey, OneToOneField, ManyToManyField)
- N+1 detection for deferred field access (
.defer()/.only()) .get()in a loop detection- Unused eager load detection (
select_related/prefetch_related) - SQL-level duplicate query detection as opt-in fallback (
NPLUS1_DETECT_DUPLICATE_QUERIES) - Call-site tracking in detection messages
NPLUS1_SHOW_ALL_CALLERSmode for full stack traces- Configurable thresholds (
NPLUS1_THRESHOLD,NPLUS1_GET_THRESHOLD,NPLUS1_DUPLICATE_QUERY_THRESHOLD) - Django middleware with sync and async support
- pytest plugin with
nplus1fixture and@pytest.mark.nplus1marker Profilercontext managernplus1_allow()context manager for local suppressionnplus1_detectedDjango signal for custom reporting- Whitelisting with wildcard support and validation against Django model registry
- Multiple notification methods: logging,
warnings.warn_explicit(), raise exception - Python 3.12+ / Django 5.2+ support