Lightweight GraphQL alternative for django-restframework
Project description
DRF Query Lang
📖 Overview
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
✨ Features
- Strict DSL (
Model{...}syntax) - Dynamic
ModelSerializergeneration - Automatic queryset optimizations
- Configurable authorization & security rules
- Ready-to-use DRF view (
QueryLangView)
🚀 Installation
pip install drf-query-lang
Or with Poetry / pyproject.toml:
dependencies = [
"drf-query-lang>=0.1.0"
]
⚙️ Configuration
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
}
📡 Usage
1. Add endpoint
# urls.py
from django.urls import path, include
urlpatterns = [
path("query-lang/", include("drf_query_lang.urls")),
]
2. Example queries
Simple fields
GET /query-lang/?query=Account{"nom","prenom"}
Response:
[
{"nom": "Durand", "prenom": "Alice"},
{"nom": "Martin", "prenom": "Bob"}
]
Relations
GET /query-lang/?query=User{"email", Profile:profile{"bio"}}
Response:
[
{"email": "a@test.com", "profile": {"bio": "Hello"}},
{"email": "b@test.com", "profile": {"bio": "World"}}
]
Functions
GET /query-lang/?query=User{"username", Post:posts:count()[{}]}
Response:
[
{"username": "jdoe", "posts": 42},
{"username": "jdupont", "posts": 7}
]
Existence check
GET /query-lang/?query=Group{"name"}&exist=true
Response:
{"exist": true}
🔒 Security
- Blocked models: defined in
UNAUTHORIZED_MODELS - Blocked fields: defined in
UNAUTHORIZED_KEYS - Authorization: checked with
AUTHORIZATION_METHOD(request)
🧪 Tests
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"]
📌 Limitations (v0.1 beta)
- 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
📜 License
MIT © 2025
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file drf_query_lang-0.0.1b1.tar.gz.
File metadata
- Download URL: drf_query_lang-0.0.1b1.tar.gz
- Upload date:
- Size: 9.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1cdcd8f4599b2cd76448ff7e76bb630165aabbf9c06d02aa3a6d0f7c3143e7fa
|
|
| MD5 |
e0ce62cc85f423acce27f424750c8cd5
|
|
| BLAKE2b-256 |
08f113ce7aaf5bfcbd03df58e29b8afb6c657f1e44e48523a7fc6d9adeda3fbf
|
File details
Details for the file drf_query_lang-0.0.1b1-py3-none-any.whl.
File metadata
- Download URL: drf_query_lang-0.0.1b1-py3-none-any.whl
- Upload date:
- Size: 9.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3d7ceef549206885f9ec22f0a1d41b4c897cbd3a490b257ccf2c1ea567521f30
|
|
| MD5 |
a7719d1495c611a836ecdea5a8de9aa4
|
|
| BLAKE2b-256 |
c3e78908b3fb72624e30fdc26b5c8624f3e94d796d3491594b8549bb60cedff8
|