djust 0.3.0rc4

Pre-releaseSecurityReleased

This is a pre-release. djust 0.3.0 has shipped since: read the djust 0.3.0 release notes.

Before you upgrade, read Removed below.

Added

  • All 57 Django template filters — The Rust template engine now supports the complete set of Django built-in filters. Added 24 filters across two batches: default_if_none, wordcount, wordwrap, striptags, addslashes, ljust, rjust, center, make_list, json_script, force_escape, escapejs, linenumbers, get_digit, iriencode, urlize, urlizetrunc, truncatechars_html, truncatewords_html, safeseq, escapeseq, unordered_list, phone2numeric, pprint. (#246, #254) See docs/website/guides/template-cheatsheet.md.
  • Authentication & Authorization — Opinionated, framework-enforced auth for LiveViews. View-level login_required and permission_required class attributes (plus LoginRequiredMixin/PermissionRequiredMixin for Django-familiar patterns). Custom auth logic via check_permissions() hook. Handler-level @permission_required() decorator for protecting individual event handlers. Auth checks run server-side before mount() and before handler dispatch — no client-side bypass possible. Integrates with djust_audit command (shows auth posture per view) and Django system checks (djust.S005 warns on unprotected views with exposed state).
  • Navigation & URL Statelive_patch() updates URL query params without remount, live_redirect() navigates to a different view over the same WebSocket. Includes handle_params() callback, live_session() URL routing helper, and client-side dj-patch/dj-navigate directives with popstate handling. (#236)
  • Presence Tracking — Real-time user presence with PresenceMixin and PresenceManager. Pluggable backends (in-memory and Redis). Includes LiveCursorMixin and CursorTracker for collaborative live cursor features. (#236) See docs/website/guides/presence.md.
  • StreamingStreamingMixin for real-time partial DOM updates (e.g., LLM token-by-token streaming). Provides stream_to(), stream_insert(), stream_text(), stream_error(), stream_start()/stream_done(), and push_state(). Batched at ~60fps to prevent flooding. (#236) See docs/website/guides/streaming-markdown.md.
  • File UploadsUploadMixin with binary WebSocket frame protocol for chunked file uploads. Includes progress tracking, magic bytes validation, file size/extension/MIME checking, and client-side dj-upload/dj-upload-drop directives. (#236) See docs/website/guides/uploads.md.
  • JS Hooksdj-hook attribute for client-side JavaScript lifecycle hooks (mounted, updated, destroyed, disconnected, reconnected). (#236)
  • Model Bindingdj-model two-way data binding with .lazy and .debounce-N modifiers. Server-side ModelBindingMixin with security field blocklist and type coercion. (#236) See docs/website/guides/model-binding.md.
  • Client Directivesdj-confirm confirmation dialogs, dj-target scoped updates, embedded view routing in event handlers. (#236)
  • Server-Push API — Background tasks (Celery, management commands, cron jobs) can now push state updates to connected LiveView clients via push_to_view(). Includes per-view channel groups (auto-joined on mount), a sync/async public API (push_to_view / apush_to_view), and periodic handle_tick() for self-updating views. (#230)
  • Progressive Web App (PWA) Support — Complete offline-first PWA implementation with service worker integration, IndexedDB/LocalStorage abstraction, optimistic UI updates, and offline-aware template directives. Includes comprehensive template tags ({% djust_pwa_head %}, {% djust_pwa_manifest %}), PWA mixins (PWAMixin, OfflineMixin, SyncMixin), and automatic synchronization when online. (#235) See docs/website/guides/pwa.md.
  • Multi-Tenant SaaS Support — Production-ready multi-tenant architecture with flexible tenant resolution strategies (subdomain, path, header, session, custom, chained), automatic data isolation, tenant-aware state backends, and comprehensive template context injection. Includes TenantMixin and TenantScopedMixin for views. (#235)
  • dj-poll attribute — Declarative polling for LiveView elements. Add dj-poll="handler_name" to any element to trigger the handler at regular intervals. Configurable via dj-poll-interval (default: 5000ms). Automatically pauses when the page is hidden and resumes on visibility change. (#269)
  • DjustMiddlewareStack — New ASGI middleware for apps that don't use django.contrib.auth. Wraps WebSocket routes with session middleware only (no auth required). Updated C005 system check to recognize both AuthMiddlewareStack and DjustMiddlewareStack. (#265)
  • System check C006 — Warns when daphne is in INSTALLED_APPS but whitenoise middleware is missing. (#259)
  • startproject / startapp / new CLI commandspython -m djust new myapp creates a full project with optional features (--with-auth, --with-db, --with-presence, --with-streaming, --from-schema). Legacy startproject and startapp commands also available. (#266)
  • djust mcp install CLI command — Automates MCP server setup for Claude Code, Cursor, and Windsurf. Tries claude mcp add first (canonical for Claude Code), falls back to writing .mcp.json directly. Merges with existing config, backs up malformed files, idempotent. See docs/website/guides/mcp-server.md.
  • Simplified root elementdj-view is now the only required attribute on LiveView container elements. The client auto-stamps dj-root and dj-liveview-root at init time. Old three-attribute format still works. (#258)
  • Model .pk in templates{{ model.pk }} now works in Rust-rendered templates. Model serialization includes a pk key with the native primary key value. (#262) See docs/website/guides/template-cheatsheet.md.
  • Better Error Messages — Improved error messages for common LiveView event handler mistakes (missing @event_handler, wrong method signature). (#248) See docs/website/guides/flash-messages.md.
  • LiveViewSmokeTest mixin — Automated smoke and fuzz testing for LiveView classes. (#251)
  • MCP serverpython manage.py djust_mcp starts a Model Context Protocol server for AI assistant integration. Provides framework introspection, system checks, scaffolding, and validation tools. Used by djust mcp install to configure Claude Code, Cursor, and Windsurf. See docs/website/guides/mcp-server.md.
  • djust_audit management command — Security audit showing auth posture, exposed state, and handler signatures per view.
  • djust_check management command — Django system checks for project validation. Gains --fix flag for safe auto-fixes and --format json for enhanced output with fix hints.
  • djust_schema management command — Extract and generate Django models from JSON schema files. See docs/guides/djust-audit.md.
  • djust_ai_context management command — Generate AI-focused context files for LLM integrations. See docs/guides/djust-audit.md.
  • AI documentationdocs/ai/ with focused guides for events, forms, JIT, lifecycle, security, and templates. docs/llms.txt and docs/llms-full.txt for LLM context.
  • Auto-build client.js from src/ modules — Pre-commit hook runs build-client.sh when src/ files change. (#211)
  • Keyed-mutation fuzz test generator — New proptest generator produces tree B by mutating tree A, exercising keyed diff paths more effectively. Proptest cases bumped from 500 to 1000. (#216, #217)

Changed

  • BREAKING: data-dj-* prefix stripping — Client-side extractTypedParams() now strips the dj_ prefix from data-dj-* attributes. data-dj-preset="dark" sends {preset: "dark"} instead of {dj_preset: "dark"}. Update handler parameter names accordingly: dj_foofoo.
  • State Backends — Enhanced with tenant-aware isolation support (TenantAwareRedisBackend, TenantAwareMemoryBackend).

Performance

  • Batched sync_to_async calls — Event handler processing now uses 2 thread hops instead of 4, saving ~1-4ms per event. (#277)
  • Eliminated JSON encode/decode roundtrip — Direct normalize_django_value() Python-to-Python type normalization replaces 17 json.loads(json.dumps(...)) patterns. Saves 2-5ms per event for views with database objects. (#279)
  • Cached template variable extraction — Rust extract_template_variables() results cached by content hash (SHA-256). Size-capped at 256 entries with automatic eviction. (#280)
  • Cached context processor resolutionresolve_context_processors() results cached per settings configuration. Invalidated on setting_changed signal. (#281)
  • JIT short-circuit for non-DB views — Views without QuerySets or Models in context skip the entire JIT serialization pipeline. Saves ~0.5ms per event for simple views. (#278)
  • Slimmer debug payload — Event responses send only state variables; handler metadata moved to initial mount as static data. ~68% smaller debug payloads (~25KB → ~8KB per event).

Fixed

  • Inline args on form eventsdj-change, dj-input, dj-blur, dj-focus now parse inline arguments (e.g., dj-change="toggle(3)") before sending to server. Also fixed state change detection to use deep copy comparison, catching in-place mutations.
  • Error overlay on intentional disconnect — Suppress "WebSocket Connection Failed" overlay during TurboNav navigation via _intentionalDisconnect flag.
  • VDOM patch failure recovery — When VDOM patches fail, the client requests recovery HTML on demand instead of reloading the page. Uses DOM morphing to preserve event listeners and form state. (#259)
  • HTTP Fallback Protocolpost() now accepts the HTTP fallback format where the event name is in the X-Djust-Event header and params are flat in the body JSON. (#255)
  • Debug panel HTTP-only mode — POST responses include _debug payload when DEBUG=True, enabling the debug panel in HTTP-only mode. (#267)
  • Silent LiveView config failures — Client JS now shows helpful console.error when no LiveView containers are found. Added system check V005 for modules not in LIVEVIEW_ALLOWED_MODULES. (#257)
  • HTTP-only mode session state on GETget() now saves view state to the session immediately when use_websocket: False. (#264)
  • use_websocket: False client-side enforcement — Setting now actually prevents WebSocket connections. (#260)
  • DOM morphing preserves event listenershtml_update now uses morphdom-style DOM diffing instead of innerHTML. (#236)
  • Textarea newlines preserved — Template whitespace stripping no longer collapses newlines inside <textarea> elements. (#236)
  • PresenceMixin crash without authtrack_presence() now checks for request.user before accessing it. (#236)
  • _skip_render support in server_pushserver_push() now checks _skip_render, preventing phantom renders and VDOM version mismatches. (#236)
  • Client-side SetText mis-targets after keyed MoveChild — MoveChild patches now include child_d for data-dj-id resolution. (#225)
  • VDOM diff/patch round-trip on keyed child reorder — Patches now processed level-by-level (shallowest parent first). (#212)
  • apply_patches djust_id-based resolution — Resolves parent nodes by djust_id instead of path-based traversal. (#216)
  • Diff engine keyed+unkeyed interleaving — Emits MoveChild patches for unkeyed element children in keyed contexts. (#219)
  • Text node targeting after keyed movesSetText patches carry djust_id when available; sync_ids propagates IDs to text nodes. (#221)
  • Tag registry test pollutionclear_tag_handlers() now restores built-in handlers in teardown. (#261)

Security

  • HTTP POST handler dispatch gatingpost() now enforces the same security model as the WebSocket path: only @event_handler-decorated methods can be invoked. Validates event names with is_safe_event_name() to block dunders and private methods.
  • Auto-escaping in Rust template engineSafeString values propagated to Rust for proper auto-escaping.
  • HTML-escaped urlize and unordered_list filters — Both filters now escape their output to prevent XSS. (#254)
  • Template tag XSS prevention — All PWA template tags now use format_html() and escape() instead of mark_safe() with f-string interpolation.
  • Sync endpoint hardening — Removed @csrf_exempt from sync_endpoint_view. Added authentication requirement, payload validation, and safe field extraction.
  • Silent exception elimination — All except: pass patterns replaced with appropriate logging calls.
  • Production JS hardened — All console.log calls guarded behind djustDebug flag.

Removed

  • _allowed_events class attribute — The backwards-compatibility escape hatch that allowed undecorated methods to be called via WebSocket or HTTP POST has been removed. All event handlers must now use the @event_handler decorator.

All releases · Atom feed