Skip to main content

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

PyPI version Python versions License


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

📖 Full Documentation

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_flex-26.2.8.tar.gz (38.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_flex-26.2.8-py3-none-any.whl (40.7 kB view details)

Uploaded Python 3

File details

Details for the file django_flex-26.2.8.tar.gz.

File metadata

  • Download URL: django_flex-26.2.8.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

Hashes for django_flex-26.2.8.tar.gz
Algorithm Hash digest
SHA256 e1e20748de4b1026108d0cdfbea3d1c75bb43cbb405cac2b750bffa3c8e59509
MD5 e9083bf96e6b4b59d71c60484f41c720
BLAKE2b-256 faeff0e4c2dedf09fce6fa44fef0e967c9adb4be2095725e89d22afbc6461e90

See more details on using hashes here.

File details

Details for the file django_flex-26.2.8-py3-none-any.whl.

File metadata

  • Download URL: django_flex-26.2.8-py3-none-any.whl
  • Upload date:
  • Size: 40.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for django_flex-26.2.8-py3-none-any.whl
Algorithm Hash digest
SHA256 b00374e6d579db6cc86bd3f842574764f2f54ddd27dfb80d1e840d67d018bab1
MD5 15dd89d4b566793569c6d097683c6254
BLAKE2b-256 1e90b17743b2a13f76071b94a54be1a73610c64d74d6b57d224777c9a5000633

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page