Metadata-Version: 2.4
Name: django-nplus1-hunter
Version: 0.1.0
Summary: A development tool to detect N+1 queries in Django.
Project-URL: Documentation, https://github.com/iamjalipo/django-nplus1-hunter#readme
Project-URL: Issues, https://github.com/iamjalipo/django-nplus1-hunter/issues
Project-URL: Source, https://github.com/iamjalipo/django-nplus1-hunter
Author-email: Developer <developer@example.com>
License-Expression: MIT
License-File: LICENSE
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: Django
Classifier: Framework :: Django :: 5.2
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.10
Requires-Dist: django>=5.2
Description-Content-Type: text/markdown

# Django N+1 Hunter

A powerful, zero-configuration middleware for detecting N+1 queries in your Django applications during development.

N+1 queries are the silent performance killers of Django apps. This tool automatically monitors your SQL executions and points you exactly to the line of code in your view or model that caused the problem. 

**Supports:** Django 5.2+ and Python 3.10+
**Databases:** Works with PostgreSQL, MySQL, SQLite, and any other Django-supported backend.

---

## Features

- **Automatic Interception:** Hooks into Django's query execution to monitor SQL statements seamlessly across all configured databases.
- **Traceback Filtering:** Analyzes the call stack to point you exactly to the line of user code that triggered the loop.
- **Production Safe:** Automatically disables itself if `DEBUG = False`. It also raises a startup warning if accidentally deployed to production.
- **Zero Dependencies:** Relies entirely on built-in Python and Django features.

---

## Installation & Setup

1. Install the package via pip:
   ```bash
   pip install django-nplus1-hunter
   ```

2. Add it to your `INSTALLED_APPS`. For safety, it is highly recommended to only add it in your local/development settings:
   ```python
   # settings.py
   if DEBUG:
       INSTALLED_APPS += [
           'django_nplus1_hunter',
       ]
   ```

3. Add the middleware to `MIDDLEWARE`. Place it near the top of the list so it can track queries generated by other middlewares (like SessionMiddleware or AuthenticationMiddleware):
   ```python
   # settings.py
   if DEBUG:
       MIDDLEWARE.insert(0, 'django_nplus1_hunter.middleware.NPlus1HunterMiddleware')
   ```

That's it! Just browse your app locally. If a view triggers an N+1 query, your runserver console will light up with a warning showing the exact file and line number.

---

## Configuration Options

You can customize the detection sensitivity by adding these variables to your `settings.py`:

```python
# Number of queries generated from the exact same line of code before it is flagged as an N+1.
# Default: 3
NPLUS1_HUNTER_THRESHOLD = 3

# The maximum number of total queries allowed in a single request before a warning is thrown.
# Default: 50
NPLUS1_HUNTER_TOTAL_THRESHOLD = 50

# A list of URL path prefixes to completely ignore. Useful for admin panels or debug toolbars.
# Default: []
NPLUS1_HUNTER_IGNORE_PATHS = [
    '/admin/',
    '/__debug__/',
]
```

## How it works under the hood

The middleware utilizes `contextlib.ExitStack` and Django's built-in `connections.all()[...].execute_wrapper` to wrap every database connection during the request/response lifecycle. When a query executes, the wrapper captures the raw SQL, execution time, and a full Python stack trace.

It filters out internal Django frames (`django/db/models/*`) to find the first frame belonging to your codebase. If that specific line of code executes more times than `NPLUS1_HUNTER_THRESHOLD`, a warning is logged.
