djust 0.2.0: Template Operators, VDOM Fixes, and a Cleaner Event Syntax
Overview
djust 0.2.0 is the first stable release following the 0.1.x series. It introduces new template operators, fixes several critical VDOM rendering bugs, and completes a breaking rename of the event binding syntax. If you're upgrading from 0.1.x, read the breaking changes section carefully.
New Features
Template and / or / in Operators
Template conditions now support boolean and membership operators with correct precedence and chaining:
{% if user.is_active and user.is_verified %}
<span class="badge badge-success">Verified</span>
{% endif %}
{% if role in allowed_roles %}
<button dj-click="admin_action">Admin</button>
{% endif %}
These work anywhere {% if %} is used, including nested conditions.
VDOM Debug Tracing
The debug_vdom Django setting now bridges directly to Rust-level VDOM tracing. Mixed keyed/unkeyed children emit developer warnings to help catch template issues early.
Breaking Changes (from 0.1.x)
These changes were introduced in the 0.2.0 alpha releases and are now finalized:
Event Binding Prefix: @ → dj-
All event attributes now use the dj- prefix instead of @:
<!-- Before (0.1.x) -->
<button @click="increment">+1</button>
<input @input="search">
<!-- After (0.2.0) -->
<button dj-click="increment">+1</button>
<input dj-input="search">
This applies to all events: dj-click, dj-input, dj-submit, dj-change, dj-keydown, dj-keyup, dj-focus, dj-blur, and dj-mouseover.
Data Attribute Renames
data-liveview-root→data-djust-rootdata-liveview-id→data-djust-id
WebSocket Message Types
connected→connectmounted→mount
Bug Fixes
Pre-rendered DOM Whitespace Preservation
WebSocket mount no longer replaces innerHTML when content was already pre-rendered via HTTP GET. Instead, data-dj-id attributes are stamped onto existing DOM elements. This fixes broken whitespace in code blocks and syntax-highlighted content.
VDOM Keyed Diffing
Unkeyed children in keyed diffing contexts are now matched by relative position, eliminating spurious insert+remove patch pairs when keyed children reorder. This significantly reduces DOM churn in lists.
Event Handler Attributes Preserved
dj-* event handler attributes are no longer stripped during VDOM patching. Previously, event bindings could disappear after a re-render.
Model List Serialization
Lists of Django Model instances are now properly serialized on initial GET requests. Previously, passing a queryset result to a template could fail silently.
Mount URL Path
WebSocket mount requests now use the actual page URL instead of a hardcoded path, fixing routing issues in multi-page applications.
Dependency Upgrades
- html5ever 0.27 → 0.36
- markup5ever_rcdom 0.3 → 0.36
- vitest 2.x → 4.x
Upgrading
pip install --upgrade djust==0.2.0
Migration steps:
- Find and replace
@click,@input, etc. withdj-click,dj-input, etc. in all templates - Replace
data-liveview-rootwithdata-djust-rootanddata-liveview-idwithdata-djust-id - If you handle WebSocket messages directly, update
connected→connectandmounted→mount - Run your test suite to catch any remaining references
A project-wide search for @click, @input, data-liveview, and "connected" should surface everything that needs updating.
What's Next
The next release will focus on WebSocket event security hardening, including rate limiting, message size limits, and an event allowlist mechanism. Follow the project on GitHub for updates.
Related Posts
djust 0.2.2: The Debug Panel Gets Real
djust 0.2.2 transforms the debug panel from a static inspector into a live development companion. Event filtering, replay, network inspection, VDOM patch tracing, and live state updates via WebSocket — all wired up and working out of the box.
djust 0.2.1: WebSocket Security Hardening with Three Layers of Defense
djust 0.2.1 locks down WebSocket event dispatch with an event name guard, @event_handler decorator allowlist, server-side rate limiting, and per-IP connection tracking. A security-focused release with zero new features to break.
Introducing djust: Reactive Django Apps Powered by Rust
djust is a Django framework for building reactive, real-time applications in pure Python — powered by a Rust VDOM engine with 30x faster rendering than Django templates. No JavaScript framework required.