Before you upgrade, read Breaking Changes, Deprecated below.
djust 0.3.6 was stabilized through 2 pre-releases, and most of its changes are recorded under them: 0.3.6rc3, 0.3.6rc4.
Breaking Changes
model.idnow returns the native type, not a string —_serialize_model_safely()previously wrappedobj.pkwithstr()when producing the"id"key, causing template comparisons like{% if edit_id == todo.id %}to fail silently whenedit_idwas an integer.model.idnow matchesmodel.pkand returns the native Python type (e.g.int,UUID). Migration: if your templates or event handlers comparemodel.idagainst string literals or string-typed variables, update them to use the native type. PR #262 fixed.pk; this PR (#472) completes the fix for.id.
Fixed
- Skip redundant
mount()on WebSocket connect for pre-rendered pages — When the client sendshas_prerendered=trueon WS connect and saved state exists in the session (written during the HTTP GET), the view's attributes are restored from session instead of re-runningmount(). This eliminates the double page-load cost for views with expensivemount()implementations (e.g. directory scans, API calls). Falls back to callingmount()normally when no saved state is found._ensure_tenant()is now called unconditionally before the restore/mount decision, fixing a regression where multi-tenant views hadself.tenant=Noneon WS connect for pre-rendered pages. (#542) djust cache --allnow correctly clears all sessions on the Redis backend — The CLI calledcleanup_expired(ttl=0)to force-clear sessions, but the semantics ofttl=0changed in 0.3.5 to mean "never expire". The command now calls the explicitdelete_all()method, which uses a Redis pipeline for an efficient single round-trip bulk delete. (#409)dj-paramsattribute no longer silently dropped — Between 0.3.2 and 0.3.6rc2,dj-paramswas removed from the client event-binding code. Templates usingdj-params='{"key": value}'continued to fire click events but the server receivedparams: {}. The attribute is now read and merged into the params object for backward compatibility. Aconsole.warnis emitted in debug mode (globalThis.djustDebug) to notify developers to migrate. (#469)- Prefetch Set not cleared on SPA navigation — The client-side
_prefetchedSet persisted acrosslive_redirectnavigations, preventing links on the new view from being prefetched. Addedclear()towindow.djust._prefetchand call it inhandleLiveRedirect()so each SPA navigation starts with a fresh prefetch state. (#402) - Auto-reload on unrecoverable VDOM state — When VDOM patch recovery fails because recovery HTML is unavailable (e.g. after server restart), the client now auto-reloads the page instead of showing a confusing error overlay. The server sends
recoverable: falseto signal the client. (#421) {% djust_pwa_head %}and other custom tags with quoted arguments containing spaces now render correctly — The Rust template lexer usedsplit_whitespace()to tokenize tag arguments, which broke quoted values likename="My App"into separate tokens (name="MyandApp"). This caused the downstream Python handler to receive malformed arguments, silently returning empty output. Replaced with a quote-aware splitter (split_tag_args) that preserves quoted strings as single arguments. (#419){% load %}tags stripped during template inheritance, breaking inclusion tags — The Rust parser treated{% load %}asNode::Comment, whichnodes_to_template_string()discarded during inheritance reconstruction. When the resolved template was re-parsed, custom tags that relied on Django tag libraries (e.g.{% djust_pwa_head %}) could silently fail. Fixed by adding a dedicatedNode::Loadvariant that preserves library names through reconstruction. Also improved_render_django_tag()error handling: failures now log a full traceback vialogger.exception()and return a visible HTML comment instead of an empty string. (#418)- Checkbox/radio
checkedand<option>selectedstate not updated by VDOM patches —SetAttrandRemoveAttrpatches only calledsetAttribute/removeAttribute, which updates the HTML attribute but not the DOM property. After user interaction the browser separates the two, so server-driven state changes viadj-clickhad no visible effect on checkboxes, radios, or select options. Fixed by syncing the DOM property alongside the attribute. Also fixedcreateNodeFromVNodeto set.checked/.selectedwhen creating new elements. (#422) SESSION_TTL=0breaks all event handling (no DOM patches) —cleanup_expired()methods in bothInMemoryStateBackendandRedisStateBackendnow treatTTL ≤ 0as "never expire". PreviouslySESSION_TTL=0causedcutoff = time.time() - 0, making all sessions appear expired, deleting them immediately, and leaving no state for VDOM patches. (#395)- WebSocket session extraction crashes on Django Channels
LazyObject— Replacedhasattr(scope_session, "session_key")withgetattr(scope_session, "session_key", None)in the consumer's request context builder.hasattr()on a Django ChannelsLazyObjectcan raise non-AttributeErrorexceptions during lazy evaluation, causing the consumer to crash silently. (#396)
Deprecated
dj-paramsJSON blob attribute — Use individualdata-*attributes with optional type-coercion suffixes instead.dj-paramswill be removed in a future release.Migration guide (0.3.2 → 0.3.6):
<!-- Before (0.3.2) --> <button dj-click="start_edit" dj-params='{"todo_id": {{ todo.id }}}'>Edit</button> <button dj-click="set_filter" dj-params='{"filter_value": "all"}'>All</button> <!-- After (0.3.6+) --> <button dj-click="start_edit" data-todo-id:int="{{ todo.id }}">Edit</button> <button dj-click="set_filter" data-filter-value="all">All</button>Type-coercion suffixes:
:int,:float,:bool,:json. Kebab-case attribute names are auto-converted tosnake_casefor server handler parameters.
Added
djust-deployCLI — newpython/djust/deploy_cli.pymodule providing deployment commands for djustlive.com. Available via thedjust-deployentry point after installation. (#437)djust-deploy login— prompts for email/password, authenticates against djustlive.com, and stores the token in~/.djustlive/credentials(mode0o600)djust-deploy logout— calls the server logout endpoint and removes the local credentials filedjust-deploy status [project]— fetches current deployment state; optionally filtered by project slugdjust-deploy deploy <project-slug>— validates the git working tree is clean, triggers a production deployment, and streams build logs to stdout--serverflag /DJUST_SERVERenv var to override the default server URL (https://djustlive.com) Seedocs/website/guides/djust-deploy.md.
TypeScript type stubs updated —
DjustStreamOpnow includes"done"and"start"operation types and an optionalmodefield ("append" | "replace" | "prepend").getActiveStreams()return type changed fromMaptoRecord. Seedocs/website/guides/typecheck.md..flex-betweenCSS utility class — Added to demo project'sutilities.cssfor laying out flex children horizontally with space-between. Use on card headers or any flex container that needs a title on the left and action widget on the right. (#397) Seedocs/website/guides/css-frameworks.md.Debug toolbar state size visualization — New "Size Breakdown" table in State tab shows per-variable memory and serialized byte sizes with human-readable formatting (B/KB/MB). Added
_debug_state_sizes()method toPostProcessingMixinincluded in both mount and event debug payloads. (#459)Debug panel TurboNav persistence — Event, patch, network, and state history now persist across TurboNav navigation via sessionStorage (30s window). Panel state restores on next page if navigated within 30 seconds. (#459) See
docs/website/advanced/debug-panel.md.TurboNav integration guide — Comprehensive guide covering setup, navigation lifecycle, inline script handling, known caveats, and design decisions:
docs/guides/turbonav-integration.md. (#459)Debug panel search extended to Network and State tabs — The search bar in the debug panel now filters across all data tabs. The Network tab shows a
N / totalcount label when a query narrows the message list (#530). The State tab filters history entries by trigger, event name, and serialized state content, with the sameN / totalcount label (#520). OverlappingnameFilterandsearchQueryon the Events tab now correctly apply AND semantics (#532). (#541)See
docs/website/advanced/debug-panel.md.