A flexible query language for Django - enable frontends to dynamically construct database queries
Project description
Django-Flex
A flexible query language for Django — let your frontend dynamically construct database queries
Your first API in 5 minutes. No serializers. No viewsets. Just config.
Features
- Field Selection — Request only the fields you need, including nested relations
- JSONField Support — Seamless dot notation for nested JSON data
- Dynamic Filtering — Full Django ORM operator support with composable AND/OR/NOT
- Smart Pagination — Limit/offset with cursor-based continuation
- Built-in Security — Row-level, field-level, and operation-level permissions
- Automatic Optimization — N+1 prevention with smart
select_related - Django-Native — Feels like a natural extension of Django
Installation
pip install django-flex
Quick Start
1. Add to Django
# settings.py
INSTALLED_APPS = ['django_flex', ...]
MIDDLEWARE = ['django_flex.middleware.FlexMiddleware', ...]
DJANGO_FLEX = {
'EXPOSE': {
# Role-first structure: role -> model -> config
'staff': {
'booking': {
'fields': ['id', 'status', 'customer.name', 'scheduled_date'],
'ops': ['get', 'list', 'add', 'edit', 'delete'],
},
},
},
}
2. Add URL
# urls.py
urlpatterns = [
path('api/', include('django_flex.urls')),
]
Done. Your API is live at /api/bookings/.
CRUD Operations
List
fetch('/api/bookings/');
{
"results": {
"1": {
"id": 1,
"status": "confirmed"
},
"2": {
"id": 2,
"status": "pending"
}
}
}
Get
fetch('/api/bookings/1');
{
"id": 1,
"status": "confirmed",
"customer": {
"name": "Aisha Khan"
}
}
Create
fetch('/api/bookings/', {
method: 'POST',
body: JSON.stringify({
customer_id: 1,
status: 'pending',
}),
});
{
"id": 3,
"status": "pending",
"customer_id": 1
}
Update
fetch('/api/bookings/1', {
method: 'PUT',
body: JSON.stringify({
status: 'completed',
}),
});
{
"id": 1,
"status": "completed"
}
Delete
fetch('/api/bookings/1', { method: 'DELETE' });
{
"deleted": true
}
Advanced Querying
All query options are sent in the request body.
Field Selection
fetch('/api/bookings/', {
method: 'GET',
body: JSON.stringify({
fields: 'id, status, customer.name',
}),
});
{
"results": {
"1": {
"id": 1,
"status": "confirmed",
"customer": {
"name": "Aisha Khan"
}
}
}
}
Nested Relations
{
fields: 'id, customer.name, customer.address.city';
}
{
"results": {
"1": {
"id": 1,
"customer": {
"name": "Aisha Khan",
"address": {
"city": "Sydney"
}
}
}
}
}
Wildcard Fields
{
fields: '*, customer.*';
}
Filtering — Exact Match
{
filters: {
status: 'confirmed';
}
}
{
"results": {
"1": {
"id": 1,
"status": "confirmed"
}
}
}
Filtering — Comparison
{
filters: {
'price.gte': 50,
'price.lte': 200
}
}
Filtering — Text Search
{
filters: {
'name.icontains': 'khan'
}
}
Filtering — List Membership
{
filters: {
'status.in': ['pending', 'confirmed']
}
}
Filtering — Null Check
{
filters: {
'assignee.isnull': true
}
}
Filtering — Date Range
{
filters: {
'created_at.gte': '2024-01-01',
'created_at.lte': '2024-12-31'
}
}
Filtering — Related Fields
{
filters: {
'customer.vip': true,
'customer.address.city': 'Sydney'
}
}
Filtering — OR Conditions
{
filters: {
or: {
status: 'pending',
urgent: true
}
}
}
Filtering — NOT Conditions
{
filters: {
not: {
status: 'cancelled';
}
}
}
Ordering
{
order_by: '-scheduled_date';
}
{
"results": {
"3": {
"scheduled_date": "2024-03-15"
},
"1": {
"scheduled_date": "2024-03-10"
}
}
}
Pagination
{
limit: 20,
offset: 0
}
{
"results": {},
"pagination": {
"offset": 0,
"limit": 20,
"has_more": true,
"next": {}
}
}
Why Django-Flex?
| Feature | Django-Flex | GraphQL | REST |
|---|---|---|---|
| Learning curve | Low (Django-native) | High | Low |
| Field selection | ✅ | ✅ | ❌ (fixed endpoints) |
| Dynamic filtering | ✅ | ✅ | Limited |
| Built-in security | ✅ | Manual | Manual |
| Django integration | Native | Requires graphene | Native |
| Schema definition | Optional | Required | N/A |
| N+1 prevention | Automatic | Manual | Manual |
Learn More
License
MIT
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 django_flex-26.2.6.tar.gz.
File metadata
- Download URL: django_flex-26.2.6.tar.gz
- Upload date:
- Size: 38.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8a9298dd692faacd3160871b48c7b17b205f322403fe77a389c30b29a58fce6d
|
|
| MD5 |
c5c16e1ac627efda29d2f4d14a17c8f5
|
|
| BLAKE2b-256 |
b384997e1f4bad56c132f19d59b8f4e44e6667db86d3725eae2eac97fc0cc845
|
File details
Details for the file django_flex-26.2.6-py3-none-any.whl.
File metadata
- Download URL: django_flex-26.2.6-py3-none-any.whl
- Upload date:
- Size: 40.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dde1623d0c2982ee118f8ef7274e8c2e37358ede2ffe37b0a995fb90d8013efc
|
|
| MD5 |
5c1008c6de49a59e5406cd7bc65a2f31
|
|
| BLAKE2b-256 |
6e59208bec736aceb1abe6daf5a11da2580a824941b49f1394975ba104e462be
|