N+1 database queries and silent query count growth can severely affect Django application performance. Unfortunately, they are often discovered too lateβin production server logs or APM dashboards.
To solve this problem, I built django-query-guardβan open-source Pytest plugin that brings database performance checks directly into automated test suites.
π‘ The Problem: Silent N+1 Queries
In Django, the ORM makes fetching related models effortless, but itβs terrifyingly easy to write an accidental N+1 loop:
python
# β N+1 Query Accident
# Fetches 100 users (1 query), then executes 100 individual queries for each profile!
# Total: 101 Database Queries! π
users = User.objects.all()
profiles = [user.profile.bio for user in users]
π‘οΈ The Solution: django-query-guard
Instead of relying on manual code reviews, django-query-guard turns query limits and N+1 prevention into enforceable Pytest assertions:
python
import pytest
@pytest.mark.django_db
@pytest.mark.query_guard(max_queries=2, detect_n_plus_one=True)
def test_user_profiles_api(client):
response = client.get("/api/users/")
assert response.status_code == 200
If your endpoint accidentally executes 101 queries instead of 2, Pytest fails instantly with an exact breakdown of which SQL statement repeated! π₯
π₯ Key Features
π― Pytest Marker Integration: @pytest.mark.query_guard(max_queries=N)
π§ Smart SQL Normalization: Parameter-variation filtering prevents false positives on intentional duplicate queries with identical parameters.
ποΈ Multi-Database Support: Monitors queries across all configured Django database connections (default, replica, etc.).
π HTML Query Reports: Dark-themed HTML report generation after test runs (pytest --query-guard-report=report.html).
π Trend History Tracking: JSON-based run history with regression detection across test builds (pytest --query-guard-trend=.query_guard_history.json).
π Wide Compatibility: Fully tested on Python 3.10β3.14 and Django 4.0β6.0.
π¦ Installation & Setup
Install the stable package from PyPI:
bash
pip install django-query-guard
Or with development tools:
bash
pip install django-query-guard[dev]
π Generating Visual HTML Reports
You can generate a dark-themed HTML query report after any test run:
bash
pytest --query-guard-report=report.html
The report includes:
Summary metrics (Total tests, pass/fail counts, total queries, N+1 detections)
Per-test query count breakdown
Detailed SQL query execution duration and parameters for failing tests
Top comments (0)