Skip to main content

Next-generation Django toolkit: typed ORM, unified validation, async-first workflows, and smart caching

Project description

Django Nova Logo

⚡ Django Nova

Typed, unified, and async-first toolkit for Django 5+

Eliminate architectural fragmentation. One schema. One truth. Zero duplication.

PyPI Python Django License pyright Latest on Django Packages

English | Русский


📋 Table of Contents


🎯 Problem Statement

Django's validation layer is fragmented by design:

  • Forms validate user input in the presentation layer.
  • DRF Serializers re-implement the same logic in the API layer.
  • Model clean() runs only inside the admin or when explicitly called.
  • Database constraints are limited to simple, DB-expressible rules and are not reusable outside the ORM.

The result is validation drift: business rules scattered across forms, serializers, models, and database DDL. Change a rule in one place, and the other three become liabilities. Worse, calling Model.objects.create() from a management command, a Celery task, or a data pipeline bypasses form and serializer validation entirely, leaving only brittle DB constraints as a safety net.

Django Nova solves this by moving the contract to the schema and enforcing it at the ORM level.


🧠 Philosophy

# Principle Description
1 Schema is the Single Source of Truth Business logic lives in Pydantic models. Django Models, DRF Serializers, FastAPI routers, and Forms are generated projections of that schema — not independent validators.
2 Validation is an ORM concern A model should refuse to persist invalid data regardless of whether the caller is a web view, an API endpoint, a CLI command, or a background worker.
3 Infrastructure must be transparent Cache invalidation, structured logging, and distributed tracing should require zero boilerplate. If you have to think about them, the abstraction has leaked.
4 Zero-downtime is the default Operations on large tables must use native PostgreSQL CONCURRENTLY semantics. Scheduled maintenance windows are an anti-pattern.
5 Type safety is not optional Full pyright --strict compatibility across ORM, QuerySets, and generated code. If it type-checks, it runs.

🏗️ Architecture

┌─────────────────────────────────────────────────────────────────────────────┐
│                           Consumer Layers                                   │
│  ┌──────────┐  ┌──────────────┐  ┌─────────────┐  ┌─────────────────────┐   │
│  │  Forms   │  │ DRF Serial.  │  FastAPI Router│  │ Management Commands │   │
│  └────┬─────┘  └──────┬───────┘  └──────┬──────┘  └───────── ─┬─────────┘   │
│       │               │                 │                     │             │
│       └───────────────┴─────────────────┴─────────────────────┘             │
│                           │                                                 │
│              ┌────────────▼────────────┐                                    │
│              │   Pydantic Schema       │  ← Single Source of Truth          │
│              │      (Business)         │                                    │
│              └────────────┬────────────┘                                    │
│                           │                                                 │
│              ┌────────────▼────────────┐                                    │
│              │      NovaModel          │  ← ORM Enforcement Layer           │
│              │     (Interceptor)       │                                    │
│              └────────────┬────────────┘                                    │
│                           │                                                 │
│       ┌───────────────────┼───────────────────┐                             │
│       │                   │                   │                             │
│  ┌────▼─────┐    ┌────────▼────────┐   ┌─────▼──────┐                       │
│  │  Cache   │    │     Signals     │   │ Telemetry  │                       │
│  │ Invalid. │    │ (post_save etc) │   │(OTel/Logs) │                       │
│  └──────────┘    └─────────────────┘   └────────────┘                       │
└─────────────────────────────────────────────────────────────────────────────┘

Core Design Decisions:

  • PEP 695 Genericsclass Cache[T]: syntax for modern type inference.
  • PEP 562 Lazy Imports — Safe import paths that bypass AppRegistryNotReady during startup.
  • SQL Compiler Hook — Deterministic cache-key generation from query AST, immune to Django version changes.
  • Signal-Driven Invalidation — O(1) cache eviction on write without manual TTL management.

Comparison

Feature Django Nova Django Ninja Django Modern drf-pydantic Vanilla Django
Validation Layer ORM save() API decorators Model layer DRF Serializers Forms / clean()
ORM Enforcement ✅ Automatic ❌ None ✅ Automatic ❌ None ⚠️ Opt-in
Schema Source Pydantic → Model Model → Schema Model fields Pydantic → Serializer Model only
Pydantic v2 ✅ Yes ✅ Yes ❌ No ✅ Yes ❌ N/A
Async ORM ✅ Native ✅ Native ❌ Sync only ❌ Sync only ⚠️ Partial
DRF Serializer Gen to_drf_serializer() ❌ No ❌ No .drf_serializer ❌ N/A
FastAPI Router Gen NovaRouter() ❌ No ❌ No ❌ No ❌ N/A
Admin Form Gen compile_admin() ❌ No ❌ No ❌ No ❌ N/A
QuerySet Cache ✅ Signal-driven ❌ No ❌ No ❌ No ❌ No
Read Replica Routing ✅ Lag-aware ❌ No ❌ No ❌ No ❌ No
Distributed Locks ✅ Redis Lua ❌ No ❌ No ❌ No ❌ No
Rate Limiting ✅ Sliding window ❌ No ❌ No ❌ No ❌ No
Pub/Sub Cache Invalidation ✅ Async facade ❌ No ❌ No ❌ No ❌ No
Zero-Downtime Migrations CONCURRENTLY ❌ No ❌ No ❌ No ❌ Locking
Structured Logging (structlog) ✅ Zero-config ❌ No ❌ No ❌ No ❌ No
OpenTelemetry Tracing ✅ Lifecycle spans ❌ No ❌ No ❌ No ❌ No
Distributed Context (correlation IDs) contextvars bridge ❌ No ❌ No ❌ No ❌ No
Auto Query Optimization ✅ Deep planner ❌ No ❌ No ❌ No ❌ No
Field Deferral ✅ Schema-driven ❌ No ❌ No ❌ No ❌ No
Type Safety pyright --strict end-to-end API layer only Limited Serializer layer only Limited
Community Size Small Large (10×) Tiny Medium Massive
Best For Multi-entry data integrity API-only projects Type-strict Django models Incremental DRF adoption Simple CRUD

One-line distinction: Django Ninja is an API framework that uses Pydantic. Django Nova is a data integrity toolkit that happens to generate APIs.

📦 Installation

Requires Python 3.12+ and Django 5.0+.

Using uv (recommended):

# Core library
uv add django-nova

# With Django REST Framework support
uv add django-nova[drf]

# With Redis infrastructure & Distributed Locks
uv add django-nova[redis]

# Full enterprise stack (tracing + structured logging)
uv add django-nova[tracing,observability]

Add to INSTALLED_APPS:

INSTALLED_APPS = [
    # ...
    "nova",
]

🚀 Quick Start

Define your business rules once in a Pydantic schema. Nova enforces them everywhere.

# models.py
from decimal import Decimal
from datetime import date
from pydantic import BaseModel, field_validator, model_validator
from django.db import models
from nova import NovaModel, NovaConfig


class GrantSchema(BaseModel):
    """Single Source of Truth for Grant business rules."""

    title: str
    budget: Decimal
    start_date: date
    end_date: date
    pi_email: str  # Principal Investigator

    @field_validator("title")
    @classmethod
    def title_not_empty(cls, v: str) -> str:
        v = v.strip()
        if len(v) < 5:
            raise ValueError("Title must be at least 5 characters")
        return v

    @model_validator(mode="after")
    def validate_grant(self):
        if self.end_date <= self.start_date:
            raise ValueError("End date must be after start date")
        return self


class Grant(NovaModel):
    title = models.CharField(max_length=300)
    budget = models.DecimalField(max_digits=14, decimal_places=2)
    start_date = models.DateField()
    end_date = models.DateField()
    pi_email = models.EmailField()

    _nova_config = NovaConfig(
        pydantic_schema=GrantSchema,
        cache_enabled=True,
        strict_validation=True,
    )

Now validation is enforced at the ORM level:

# This raises ValidationError immediately — no DB round-trip required
Grant.objects.create(
    title="X",
    budget=Decimal("500"),
    start_date=date(2026, 1, 1),
    end_date=date(2026, 12, 31),
    pi_email="pi@example.com",
)
# ValueError: Title must be at least 5 characters

🔌 Schema Compiler (DRF & Admin)

Why write serializers and admin forms if the schema already knows the rules? Nova dynamically compiles them.

DRF Integration

# serializers.py
from nova.ecosystem import to_drf_serializer
from .models import Grant

# Dynamically generates a strict ModelSerializer bound to GrantSchema
GrantSerializer = to_drf_serializer(Grant)

Note: The generated serializer strictly exposes ONLY fields defined in the Pydantic schema (+ PK). Sensitive DB fields not present in the schema are automatically hidden from the API.

Django Admin Integration

# admin.py
from django.contrib import admin
from nova.ecosystem import compile_admin
from .models import Grant

# Compiles an Admin class that intercepts Form validation via Pydantic
admin.site.register(Grant, compile_admin(Grant))

🧭 Smart Query Planner

Tell Nova what you need via the schema, and it optimizes the SQL for you.

class ArticleSchema(BaseModel):
    title: str
    author: AuthorSchema    # Triggers select_related
    tags: list[TagSchema]   # Triggers prefetch_related

class Article(NovaModel):
    title = models.CharField(max_length=200)
    body = models.TextField()  # NOT in schema!
    author = models.ForeignKey(Author, on_delete=models.CASCADE)
    _nova_config = NovaConfig(pydantic_schema=ArticleSchema)

Auto-Optimization:

qs = Article.objects.filter(title__icontains="django").auto()

Generates:

SELECT article.id, article.title, article.author_id
FROM article
INNER JOIN author ON article.author_id = author.id
WHERE article.title LIKE '%django%';
-- DEFERRED: article.body (because it's missing in ArticleSchema)

🔭 Distributed Context & Observability

Enterprise logging requires correlation. If a request hits a View, fails in the ORM, and retries in a Celery task, you need to link them.

# In your Django Middleware
from nova.core import bind, clear

class CorrelationMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        request_id = request.headers.get("X-Request-ID", "unknown")
        bind(correlation_id=request_id, user_id=request.user.id)

        response = self.get_response(request)
        clear()  # Prevent context leaks
        return response

Result: Every structlog JSON log and every OpenTelemetry span automatically includes correlation_id and user_id. Zero boilerplate in your business logic.


🏭 Infrastructure (Redis & Replicas)

Unified Redis Client

No more connection sprawl. Cache, Locks, and Tasks share a single process-wide pool.

from nova.redis import get_redis_client, check_redis_health

client = get_redis_client()
health = check_redis_health()  # Returns RedisHealthReport(is_healthy=True, latency_ms=0.4)

Lag-Aware Read Replicas

# In settings.py
DATABASE_ROUTERS = ["nova.db.NovaDatabaseRouter"]

# In your code
qs = Article.objects.using_replica().all()

If the replica's replication lag exceeds NOVA_REPLICA_MAX_LAG_MS (default 500ms), Nova transparently falls back to the Master to prevent serving stale data. No developer intervention required.

Distributed Locks

from nova.redis import AsyncDistributedLock

async with AsyncDistributedLock("migration_key", timeout=10.0):
    # Safe to run concurrent tasks without race conditions
    await run_heavy_migration()

💾 Smart Cache

Nova provides an automatic, signal-driven QuerySet cache with O(1) invalidation.

class Grant(NovaModel):
    # ... fields ...
    _nova_config = NovaConfig(
        pydantic_schema=GrantSchema,
        cache_enabled=True,
        cache_ttl_seconds=300,
    )
  • Deterministic keys — Generated from the SQL AST.
  • No stale data — Write operations trigger signal-based eviction.
  • Zero boilerplate — No manual cache key management.

🔄 Zero-Downtime Migrations

For tables with millions of rows, standard CREATE INDEX acquires an exclusive lock. Nova provides migration operations that use PostgreSQL CONCURRENTLY.

from nova.db import AddFieldConcurrently, CreateIndexConcurrently

class Migration(migrations.Migration):
    operations = [
        AddFieldConcurrently(
            model_name="grant",
            name="funding_program",
            field=models.CharField(max_length=100, default="NSF"),
        ),
        CreateIndexConcurrently(
            model_name="grant",
            fields=["start_date", "end_date"],
            name="grant_dates_idx",
        ),
    ]

📊 Benchmarks

All benchmarks measure model initialization speed (object creation + validation) on Python 3.13, local SSD, warm CPU, GC disabled.

$ uv run ruff check .
All checks passed!

$ uv run pytest -v
73 passed, 7 skipped in 1.65s

$ uv run python scripts/bench.py
Running 100,000 iterations (GC Disabled)...

==================================================
Pure Pydantic:     0.663 µs/iter
NovaModel (Full):  1.818 µs/iter
Overhead Ratio:    2.74x
Absolute Overhead: +1.155 µs
==================================================
Test Avg Time Ops / Second Overhead
Pure Pydantic (Baseline) 0.663 µs 1,508K 1.0×
NovaModel (Full) 1.818 µs 550K 2.74×

Note: The absolute penalty is only 1.155 microseconds per object. You gain full ORM-level type safety, unified validation, deep tracing, cache abstraction, async query planning, distributed locks, rate limiting, and pub/sub — at the cost of a single microsecond.

Test suite: 73 passed, 7 skipped in 1.65s. Zero lint errors.


🗺️ Roadmap

✅ What is Built (v0.4.0)

Category Feature Status Notes
Core Engine Typed ORM, Managers, QuerySets ✅ Stable Full pyright --strict compatibility
Pydantic Bridge & Unified Validation ✅ Stable Bidirectional sync, single source of truth
Full Async ORM Integration ✅ Stable Native AsyncTypedQuerySet with .aauto() planner
Ecosystem Auto DRF Serializer Generation ✅ Stable Strict projection, Pydantic validation injection
(Schema Compiler) Auto Django Admin Generation ✅ Stable Dynamic Forms with Pydantic clean() hooks
Admin JSON UI Schema Generator ✅ Stable Extracts validation rules for Frontend
Query Engine Deep Query Planner ✅ Stable Recursive graph traversal for JOINs
Auto Field Deferral ✅ Stable Omits DB columns not present in Pydantic schema
Infrastructure Unified Redis Client & Pool ✅ Stable Sync/Async pools, health checks, zero sprawl
Distributed Locks ✅ Stable Lua-scripted async locks for Zero-Downtime
Distributed Rate Limiter ✅ Stable Atomic Sliding Window via Lua scripts
Async Pub/Sub Facade ✅ Stable Real-time inter-process cache invalidation
Lag-Aware Read Replica Router ✅ Stable Thread-safe local cache, automatic Master failover
Zero-Downtime Migrations ✅ Stable CONCURRENTLY operations out of the box
Observability OTEL Tracing & Structlog ✅ Stable Zero-config lifecycle spans
Distributed Context (Correlation IDs) ✅ Stable contextvars bridge to Logs & Traces
Platform Stable Public API (Frozen) ✅ Stable PEP 562 Facades, Semver compliant
Django System Checks ✅ Stable Fail-fast infrastructure validation

🚧 Future Work

Feature ETA
GraphQL Schema Compiler (Strawberry) Q2 2027

📊 Overall Progress

████████████████████████████████████████ 100%  Core Features
████████████████████████████████████████ 100%  Infrastructure
████████████████████████████████████████ 100%  Production Readiness

Current Phase: 100% Enterprise Ready.


📄 License

MIT License. See LICENSE for details.


👤 Author

Artem Alimpiev

  • ORCID: 0009-0007-6740-7242
  • DOI: 10.5281/zenodo.20057443
  • DOI: 10.5281/zenodo.20659647
  • PyPI: Django Nova

Django Nova Logo

⚡ Django Nova

Типизированный, унифицированный и async-first тулкит для Django 5+

Устраните архитектурную фрагментацию. Одна схема. Одна истина. Ноль дублирования.


📋 Содержание


🎯 Постановка проблемы

Валидационный слой Django фрагментирован по дизайну:

  • Forms валидируют пользовательский ввод в презентационном слое.
  • DRF Serializers переизобретают ту же логику в API-слое.
  • Model clean() запускается только в админке или при явном вызове.
  • Ограничения БД ограничены простыми правилами, выразимыми в SQL, и не переиспользуются вне ORM.

Результат — дрейф валидации: бизнес-правила разбросаны по формам, сериализаторам, моделям и DDL базы данных. Измени правило в одном месте — и три других становятся уязвимостями. Хуже того, вызов Model.objects.create() из management command, Celery-таска или data pipeline полностью обходит валидацию форм и сериализаторов, оставляя лишь хрупкие ограничения БД в качестве последней линии обороны.

Django Nova решает это, перенося контракт в схему и принудительно применяя её на уровне ORM.


🧠 Философия

# Принцип Описание
1 Схема — единый источник истины Бизнес-логика живёт в Pydantic-моделях. Django Models, DRF Serializers, FastAPI-роутеры и Forms — это генерируемые проекции схемы, а не независимые валидаторы.
2 Валидация — это задача ORM Модель должна отказываться сохранять невалидные данные независимо от того, кто вызвал — веб-вью, API-эндпоинт, CLI-команда или фоновый воркер.
3 Инфраструктура должна быть прозрачной Инвалидация кеша, структурированное логирование и распределённая трассировка не должны требовать бойлерплейта. Если вы о них думаете — абстракция протекла.
4 Zero-downtime — дефолтное предположение Операции на больших таблицах должны использовать нативную семантику PostgreSQL CONCURRENTLY. Запланированные окна обслуживания — антипаттерн.
5 Типобезопасность не опциональна Полная совместимость с pyright --strict на уровне ORM, QuerySets и генерируемого кода. Если проходит type-check — работает.

🏗️ Архитектура

┌─────────────────────────────────────────────────────────────────────────────┐
│                           Потребительские слои                              │
│  ┌──────────┐  ┌──────────────┐  ┌─────────────┐  ┌─────────────────────┐   │
│  │  Forms   │  │ DRF Serial.  │  FastAPI Router│  │ Management Commands │   │
│  └────┬─────┘  └──────┬───────┘  └──────┬──────┘  └──────────┬──────────┘   │
│       │               │                  │                     │            │
│       └───────────────┴──────────────────┴─────────────────────┘            │
│                           │                                                 │
│              ┌────────────▼────────────┐                                    │
│              │   Pydantic Schema       │  ← Единый источник истины          │
│              │      (Business)         │                                    │
│              └────────────┬────────────┘                                    │
│                           │                                                 │
│              ┌────────────▼────────────┐                                    │
│              │      NovaModel          │  ← Слой принудительного ORM        │
│              │     (Interceptor)       │                                    │
│              └────────────┬────────────┘                                    │
│                           │                                                 │
│       ┌───────────────────┼───────────────────┐                             │
│       │                   │                   │                             │
│  ┌────▼─────┐    ┌────────▼────────┐   ┌─────▼──────┐                       │
│  │  Кеш     │    │     Сигналы     │   │ Телеметрия │                       │
│  │Invalid.  │    │ (post_save etc) │   │(OTel/Logs) │                       │
│  └──────────┘    └─────────────────┘   └────────────┘                       │
└─────────────────────────────────────────────────────────────────────────────┘

Ключевые архитектурные решения:

  • PEP 695 Generics — синтаксис class Cache[T]: для современного type inference.
  • PEP 562 Lazy Imports — безопасные пути импорта, обходящие AppRegistryNotReady при старте.
  • SQL Compiler Hook — детерминированная генерация кеш-ключей из AST запроса, независимая от версии Django.
  • Signal-Driven Invalidation — O(1) инвалидация кеша при записи без ручного управления TTL.

📦 Установка

Требуется Python 3.12+ и Django 5.0+.

Используя uv (рекомендуется):

# Ядро библиотеки
uv add django-nova

# С поддержкой Django REST Framework
uv add django-nova[drf]

# С Redis-инфраструктурой и распределёнными блокировками
uv add django-nova[redis]

# Полный enterprise-стек (трассировка + структурированное логирование)
uv add django-nova[tracing,observability]

Добавьте в INSTALLED_APPS:

INSTALLED_APPS = [
    # ...
    "nova",
]

🚀 Быстрый старт

Определите бизнес-правила один раз в Pydantic-схеме. Nova применяет их везде.

# models.py
from decimal import Decimal
from datetime import date
from pydantic import BaseModel, field_validator, model_validator
from django.db import models
from nova import NovaModel, NovaConfig


class GrantSchema(BaseModel):
    """Единый источник истины для бизнес-правил Grant."""

    title: str
    budget: Decimal
    start_date: date
    end_date: date
    pi_email: str  # Главный исследователь

    @field_validator("title")
    @classmethod
    def title_not_empty(cls, v: str) -> str:
        v = v.strip()
        if len(v) < 5:
            raise ValueError("Title must be at least 5 characters")
        return v

    @model_validator(mode="after")
    def validate_grant(self):
        if self.end_date <= self.start_date:
            raise ValueError("End date must be after start date")
        return self


class Grant(NovaModel):
    title = models.CharField(max_length=300)
    budget = models.DecimalField(max_digits=14, decimal_places=2)
    start_date = models.DateField()
    end_date = models.DateField()
    pi_email = models.EmailField()

    _nova_config = NovaConfig(
        pydantic_schema=GrantSchema,
        cache_enabled=True,
        strict_validation=True,
    )

Теперь валидация принудительно применяется на уровне ORM:

# Это бросает ValidationError мгновенно — без запроса к БД
Grant.objects.create(
    title="X",
    budget=Decimal("500"),
    start_date=date(2026, 1, 1),
    end_date=date(2026, 12, 31),
    pi_email="pi@example.com",
)
# ValueError: Title must be at least 5 characters

🔌 Компилятор схем (DRF & Admin)

Зачем писать сериализаторы и админ-формы, если схема уже знает правила? Nova динамически компилирует их.

Интеграция с DRF

# serializers.py
from nova.ecosystem import to_drf_serializer
from .models import Grant

# Динамически генерирует строгий ModelSerializer, привязанный к GrantSchema
GrantSerializer = to_drf_serializer(Grant)

Примечание: Сгенерированный сериализатор строго экспонирует ТОЛЬКО поля, определённые в Pydantic-схеме (+ PK). Чувствительные поля БД, отсутствующие в схеме, автоматически скрыты из API.

Интеграция с Django Admin

# admin.py
from django.contrib import admin
from nova.ecosystem import compile_admin
from .models import Grant

# Компилирует Admin-класс, перехватывающий валидацию форм через Pydantic
admin.site.register(Grant, compile_admin(Grant))

🧭 Умный планировщик запросов

Скажите Nova, что вам нужно, через схему — и он оптимизирует SQL за вас.

class ArticleSchema(BaseModel):
    title: str
    author: AuthorSchema    # Триггерит select_related
    tags: list[TagSchema]   # Триггерит prefetch_related

class Article(NovaModel):
    title = models.CharField(max_length=200)
    body = models.TextField()  # НЕТ в схеме!
    author = models.ForeignKey(Author, on_delete=models.CASCADE)
    _nova_config = NovaConfig(pydantic_schema=ArticleSchema)

Авто-оптимизация:

qs = Article.objects.filter(title__icontains="django").auto()

Генерирует:

SELECT article.id, article.title, article.author_id
FROM article
INNER JOIN author ON article.author_id = author.id
WHERE article.title LIKE '%django%';
-- ОТЛОЖЕНО: article.body (потому что его нет в ArticleSchema)

🔭 Распределённый контекст и наблюдаемость

Enterprise-логирование требует корреляции. Если запрос попадает во View, падает в ORM и ретраится в Celery-таске — их нужно связать.

# В вашем Django Middleware
from nova.core import bind, clear

class CorrelationMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        request_id = request.headers.get("X-Request-ID", "unknown")
        bind(correlation_id=request_id, user_id=request.user.id)

        response = self.get_response(request)
        clear()  # Предотвращаем утечку контекста
        return response

Результат: Каждый structlog JSON-лог и каждый OpenTelemetry-спан автоматически включают correlation_id и user_id. Ноль бойлерплейта в бизнес-логике.


🏭 Инфраструктура (Redis & Реплики)

Единый Redis-клиент

Никакого разрастания соединений. Кеш, блокировки и таски делят один process-wide пул.

from nova.redis import get_redis_client, check_redis_health

client = get_redis_client()
health = check_redis_health()  # Возвращает RedisHealthReport(is_healthy=True, latency_ms=0.4)

Read-реплики с учётом лага

# В settings.py
DATABASE_ROUTERS = ["nova.db.NovaDatabaseRouter"]

# В коде
qs = Article.objects.using_replica().all()

Если репликационный лаг превышает NOVA_REPLICA_MAX_LAG_MS (по умолчанию 500мс), Nova прозрачно переключается на Master, предотвращая отдачу stale-данных. Без вмешательства разработчика.

Распределённые блокировки

from nova.redis import AsyncDistributedLock

async with AsyncDistributedLock("migration_key", timeout=10.0):
    # Безопасно запускать конкурентные таски без race conditions
    await run_heavy_migration()

💾 Умный кеш

Nova предоставляет автоматический, signal-driven кеш QuerySet с O(1) инвалидацией.

class Grant(NovaModel):
    # ... поля ...
    _nova_config = NovaConfig(
        pydantic_schema=GrantSchema,
        cache_enabled=True,
        cache_ttl_seconds=300,
    )
  • Детерминированные ключи — генерируются из SQL AST.
  • Нет stale-данных — операции записи триггерят signal-based eviction.
  • Ноль бойлерплейта — ручное управление кеш-ключами не требуется.

🔄 Миграции без простоя

Для таблиц с миллионами строк стандартный CREATE INDEX захватывает эксклюзивную блокировку. Nova предоставляет операции миграций, использующие PostgreSQL CONCURRENTLY.

from nova.db import AddFieldConcurrently, CreateIndexConcurrently

class Migration(migrations.Migration):
    operations = [
        AddFieldConcurrently(
            model_name="grant",
            name="funding_program",
            field=models.CharField(max_length=100, default="NSF"),
        ),
        CreateIndexConcurrently(
            model_name="grant",
            fields=["start_date", "end_date"],
            name="grant_dates_idx",
        ),
    ]

📊 Бенчмарки

Все бенчмарки измеряют скорость инициализации модели (создание объекта + валидация) на Python 3.13, локальный SSD, разогретый CPU, GC отключён.

$ uv run ruff check .
All checks passed!

$ uv run pytest -v
73 passed, 7 skipped in 1.65s

$ uv run python scripts/bench.py
Running 100,000 iterations (GC Disabled)...

==================================================
Pure Pydantic:     0.663 µs/iter
NovaModel (Full):  1.818 µs/iter
Overhead Ratio:    2.74x
Absolute Overhead: +1.155 µs
==================================================
Тест Среднее время Ops / секунду Оверхед
Pure Pydantic (Baseline) 0.663 µs 1,508K 1.0×
NovaModel (Full) 1.818 µs 550K 2.74×

Примечание: Абсолютный штраф составляет всего 1.155 микросекунды на объект. Вы получаете полную типобезопасность на уровне ORM, унифицированную валидацию, глубокую трассировку, кеш-абстракцию, async планировщик запросов, распределённые блокировки, rate limiting и pub/sub — за цену одной микросекунды.

Тесты: 73 passed, 7 skipped за 1.65s. Ноль ошибок линтера.


🗺️ Дорожная карта

✅ Реализовано (v0.4.0)

Категория Фича Статус Примечания
Core Engine Typed ORM, Managers, QuerySets ✅ Стабильно Полная совместимость с pyright --strict
Pydantic Bridge & Unified Validation ✅ Стабильно Двусторонняя синхронизация, единый источник истины
Full Async ORM Integration ✅ Стабильно Нативный AsyncTypedQuerySet с планировщиком .aauto()
Ecosystem Auto DRF Serializer Generation ✅ Стабильно Строгая проекция, инжекция Pydantic-валидации
(Компилятор схем) Auto Django Admin Generation ✅ Стабильно Динамические Forms с Pydantic clean() хуками
Admin JSON UI Schema Generator ✅ Стабильно Извлечение правил валидации для Frontend
Query Engine Deep Query Planner ✅ Стабильно Рекурсивный обход графа для JOINs
Auto Field Deferral ✅ Стабильно Пропуск столбцов БД, отсутствующих в Pydantic-схеме
Infrastructure Unified Redis Client & Pool ✅ Стабильно Sync/Async пулы, health checks, zero sprawl
Distributed Locks ✅ Стабильно Lua-scripted async блокировки для Zero-Downtime
Distributed Rate Limiter ✅ Стабильно Атомарное Sliding Window через Lua-скрипты
Async Pub/Sub Facade ✅ Стабильно Real-time межпроцессная инвалидация кеша
Lag-Aware Read Replica Router ✅ Стабильно Thread-safe локальный кеш, авто-failover на Master
Zero-Downtime Migrations ✅ Стабильно Операции CONCURRENTLY из коробки
Observability OTEL Tracing & Structlog ✅ Стабильно Zero-config lifecycle spans
Distributed Context (Correlation IDs) ✅ Стабильно contextvars мост к Logs & Traces
Platform Stable Public API (Frozen) ✅ Стабильно PEP 562 Facades, Semver compliant
Django System Checks ✅ Стабильно Fail-fast валидация инфраструктуры

🚧 В разработке

Фича ETA
GraphQL Schema Compiler (Strawberry) Q2 2027

📊 Общий прогресс

████████████████████████████████████████ 100%  Core Features
████████████████████████████████████████ 100%  Infrastructure
████████████████████████████████████████ 100%  Production Readiness

Текущая фаза: 100% Enterprise Ready.


📄 Лицензия

MIT License. Подробности в LICENSE.


👤 Автор

Artem Alimpiev

  • ORCID: 0009-0007-6740-7242
  • DOI: 10.5281/zenodo.20057443
  • DOI: 10.5281/zenodo.20659647
  • PyPI: Django Nova

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_nova-0.4.1.tar.gz (54.7 kB view details)

Uploaded Source

Built Distribution

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

django_nova-0.4.1-py3-none-any.whl (71.3 kB view details)

Uploaded Python 3

File details

Details for the file django_nova-0.4.1.tar.gz.

File metadata

  • Download URL: django_nova-0.4.1.tar.gz
  • Upload date:
  • Size: 54.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for django_nova-0.4.1.tar.gz
Algorithm Hash digest
SHA256 001fe33197f0733164dd015bc87e7cbc608751f3e22c1c7c9c7e55c435354b0a
MD5 8b3322475d7655abfb5203122599af46
BLAKE2b-256 540db90c03bfb005dea4c75c1b721d69f716ac829f4f820730a121d5b7667d77

See more details on using hashes here.

File details

Details for the file django_nova-0.4.1-py3-none-any.whl.

File metadata

  • Download URL: django_nova-0.4.1-py3-none-any.whl
  • Upload date:
  • Size: 71.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for django_nova-0.4.1-py3-none-any.whl
Algorithm Hash digest
SHA256 f4679d2da03efde42e99cd6afa93662fad3afd5c1136e2fcdfae5bc9cc5021c1
MD5 edb6964cd721a0248b978f3419ad704e
BLAKE2b-256 c75d5a52575940d88da838476c806dc5f964e96d9ee668f13e1f39823187e6b4

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