DRF Query Lang is a lightweight query language for Django REST Framework. It allows API clients to dynamically define:
- Which fields to fetch
- Which relations to expand
- Apply simple functions (
count,min,max)
It automatically generates:
- Optimized querysets (
select_related,prefetch_related) - Dynamic DRF serializers
- Strict DSL (
Model{...}syntax) - Dynamic
ModelSerializergeneration - Automatic queryset optimizations
- Configurable authorization & security rules
- Ready-to-use DRF view (
QueryLangView)
pip install drf-query-langOr with Poetry / pyproject.toml:
dependencies = [
"drf-query-lang>=0.1.0"
]In your Django settings.py:
DRF_QUERY_LANG = {
"UNAUTHORIZED_MODELS": ["User"], # forbidden models
"UNAUTHORIZED_KEYS": ["password", "is_staff", "is_superuser"], # forbidden fields
"AUTHORIZATION_METHOD": "drf_query_lang.permission.base_permission", # request -> bool
}# urls.py
from django.urls import path, include
urlpatterns = [
path("query-lang/", include("drf_query_lang.urls")),
]GET /query-lang/?query=Account{"nom","prenom"}
Response:
[
{"nom": "Durand", "prenom": "Alice"},
{"nom": "Martin", "prenom": "Bob"}
]GET /query-lang/?query=User{"email", Profile:profile{"bio"}}
Response:
[
{"email": "a@test.com", "profile": {"bio": "Hello"}},
{"email": "b@test.com", "profile": {"bio": "World"}}
]GET /query-lang/?query=User{"username", Post:posts:count()[{}]}
Response:
[
{"username": "jdoe", "posts": 42},
{"username": "jdupont", "posts": 7}
]GET /query-lang/?query=Group{"name"}&exist=true
Response:
{"exist": true}- Blocked models: defined in
UNAUTHORIZED_MODELS - Blocked fields: defined in
UNAUTHORIZED_KEYS - Authorization: checked with
AUTHORIZATION_METHOD(request)
Run the test suite:
pytest tests/Example parser test:
def test_parse_simple_fields():
query = 'Agent{"nom","prenom"}'
parser = QueryLangParser(query)
parsed = parser.parsed_data
assert parsed["model"] == "Agent"
assert "nom" in parsed["fields"]
assert "prenom" in parsed["fields"]- Only
min,max,countfunctions supported - No pagination in the view yet
- No automatic cycle detection (self-relations may cause infinite recursion)
- Strict syntax: no spaces allowed in the top-level query
Model {}will raise an error
MIT © 2025