Mixin reference
All 17Mixin mixins that add capability to a LiveView.
Mixins add capability to a LiveView by composition — add one to your class's bases to unlock its methods and template integration. Several (StreamingMixin, FlashMixin, PageMetadataMixin, ModelBindingMixin) are included on every LiveView already; the rest you add explicitly when you need them.
Real-time
Streaming, presence, notifications, asyncMixins for live, pushing-to-the-client features: streaming responses and large collections, user presence and cursors, PostgreSQL notifications, and background work. Several are already included on every LiveView, so their methods are available without adding the mixin.
StreamingMixin
Token-by-token streaming over the WebSocket (LLM responses, live feeds). stream_start(), stream_text(), stream_to(), stream_done()
Provides
stream_start(), stream_text(), stream_to(), stream_done()
Pairs with
dj-stream
Adds token-by-token streaming over the WebSocket with automatic ~60fps batching — ideal for LLM responses and live feeds. Auto-included on every LiveView, so the stream_* methods are always available.
from djust.streaming import StreamingMixin
from djust import LiveView
class ChatView(StreamingMixin, LiveView):
@event_handler()
async def send(self, content="", **kwargs):
await self.stream_start('response')
async for token in llm_stream(content):
await self.stream_text('response', token)
await self.stream_done('response')
StreamsMixin
Efficient large collections via insert/delete/prune ops, not full re-renders. stream(), stream_insert(), stream_prune()
Provides
stream(), stream_insert(), stream_prune()
Pairs with
dj-stream container
Manages large collections efficiently by emitting insert/delete/prune ops instead of re-rendering the whole list, clearing the data from server memory after each render. Auto-included on every LiveView.
class FeedView(LiveView):
def mount(self, request, **kwargs):
self.stream('feed', Item.objects.all()[:20])
@event_handler()
def load_more(self, **kwargs):
self.stream('feed', next_batch, at=-1)
PresenceMixin
Phoenix-style presence tracking via Redis/cache: tracks per-user metadata and broadcasts join/leave. track_presence(), list_presences()
Provides
track_presence(), list_presences()
Pairs with
presence_key attribute
Phoenix-style presence tracking via Redis/cache: tracks per-user metadata and broadcasts join/leave. Set presence_key (supports {var} interpolation) and call track_presence() in mount(). Add explicitly.
from djust.presence import PresenceMixin
class DocView(PresenceMixin, LiveView):
presence_key = 'document:{doc_id}'
def mount(self, request, doc_id=None, **kwargs):
self.track_presence(meta={'name': request.user.username})
LiveCursorMixin
Extends PresenceMixin to broadcast live cursor positions for collaborative editing. get_cursors(), handle_cursor_move()
Provides
get_cursors(), handle_cursor_move()
Pairs with
presence_key attribute
Extends PresenceMixin to broadcast live cursor positions for collaborative editing. Stores cursor coordinates per user in the presence group and exposes get_cursors() for rendering. Add explicitly.
from djust.presence import LiveCursorMixin
class Editor(LiveCursorMixin, LiveView):
presence_key = 'editor:{doc_id}'
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
ctx['cursors'] = self.get_cursors()
return ctx
NotificationMixin
Bridges PostgreSQL pg_notify channels to LiveView handlers. listen(), handle_info()
Provides
listen(), handle_info()
Pairs with
@notify_on_save model decorator
Bridges PostgreSQL pg_notify channels to LiveView handlers. Call listen('channel') in mount() and handle messages in handle_info(). Pair with @notify_on_save on models. Auto-included; requires psycopg + Channels.
class OrderBoard(LiveView):
def mount(self, request, **kwargs):
self.listen('orders')
def handle_info(self, message):
if message['type'] == 'db_notify':
self.orders = Order.objects.filter(status='pending')
AsyncWorkMixin
Run slow work in the background and re-render when it finishes. start_async(), cancel_async()
Provides
start_async(), cancel_async()
Pairs with
handle_async_result()
Lets handlers flush state to the client immediately and then run slow work in a background thread, re-rendering on completion. Auto-included on every LiveView.
class ReportView(LiveView):
@event_handler()
def run(self, **kwargs):
self.generating = True # shown instantly
self.start_async(self._build, name='report')
def _build(self):
self.report = expensive()
self.generating = False
Forms & data
Forms, wizards, model binding, uploads, draftsMixins for data entry: Django form binding with live validation, multi-step wizards, two-way dj-model binding, chunked file uploads, and localStorage draft auto-save. Add the ones your view needs to its base classes.
FormMixin
Integrate a Django Form with real-time validation. form_class, form_data, get_field_errors()
Provides
form_class, form_data, get_field_errors()
Pairs with
dj-change / dj-submit
Integrates a Django Form into a LiveView with real-time validation, serialising form_data, form_choices and form_errors into state. Override form_valid()/form_invalid(). Add explicitly.
from djust.forms import FormMixin
class SignupView(FormMixin, LiveView):
form_class = SignupForm
def form_valid(self, form):
User.objects.create(**form.cleaned_data)
self.put_flash('success', 'Account created!')
WizardMixin
Multi-step form wizard with per-step validation and progress tracking. next_step(), prev_step(), submit_wizard()
Provides
next_step(), prev_step(), submit_wizard()
Pairs with
wizard_steps attribute
Multi-step form wizard with per-step validation and progress tracking. Define wizard_steps and override on_wizard_complete(step_data). Place before LiveView in the MRO. Add explicitly.
from djust.wizard import WizardMixin
class ClaimWizard(WizardMixin, LiveView):
wizard_steps = [
{'name': 'personal', 'form_class': PersonalForm},
{'name': 'review'},
]
def on_wizard_complete(self, step_data):
Claim.objects.create(**step_data['personal'])
ModelBindingMixin
Powers dj-model two-way binding with type coercion and security checks. update_model() handler
Provides
update_model() handler
Pairs with
dj-model
Powers dj-model two-way binding: provides the update_model handler that sets view attributes from the client with type coercion and security checks (private/forbidden fields blocked, allowed_model_fields honoured). Auto-included on every LiveView.
class SearchView(LiveView):
def mount(self, request, **kwargs):
self.search_query = '' # dj-model="search_query" syncs this
UploadMixin
Chunked, resumable file uploads with preview, progress, and validation. allow_upload(), consume_uploaded_entries()
Provides
allow_upload(), consume_uploaded_entries()
Pairs with
dj-upload
Adds chunked, resumable file uploads over the WebSocket with client preview/progress and server-side magic-byte validation. Configure slots with allow_upload() and read files with consume_uploaded_entries(). Add explicitly.
from djust.uploads import UploadMixin
class ProfileView(UploadMixin, LiveView):
def mount(self, request, **kwargs):
self.allow_upload('avatar', accept='.jpg,.png')
@event_handler()
def save(self, **kwargs):
for e in self.consume_uploaded_entries('avatar'):
default_storage.save(e.client_name, e.file)
DraftModeMixin
Auto-saves form drafts to the browser's localStorage (debounced ~500ms) and restores them on load. clear_draft(), get_draft_key()
Provides
clear_draft(), get_draft_key()
Pairs with
data-draft-* attributes
Auto-saves form drafts to the browser's localStorage (debounced ~500ms) and restores them on load. Set draft_enabled and draft_key, and clear_draft() on a successful save. Add explicitly.
from djust.drafts import DraftModeMixin
class ArticleEditor(DraftModeMixin, LiveView):
draft_enabled = True
draft_key = 'article_editor'
@event_handler()
def save(self, title='', content='', **kwargs):
Article.objects.create(title=title, content=content)
self.clear_draft()
UI & feedback
Flash, page metadata, activity regionsMixins for UI feedback and state that lives alongside the render: flash messages, dynamic document title/meta tags, and pre-rendered Activity regions that keep hidden UI's state alive. These are included on every LiveView.
FlashMixin
Queues transient notifications during a handler; the WebSocket consumer flushes them to the client after the response. put_flash(), clear_flash()
Provides
put_flash(), clear_flash()
Pairs with
{% flash %} tag
Queues transient notifications during a handler; the WebSocket consumer flushes them to the client after the response. level becomes the dj-flash-{level} CSS class. Auto-included on every LiveView.
@event_handler()
def save(self, **kwargs):
do_save()
self.put_flash('success', 'Saved!')
PageMetadataMixin
Lets a handler update the document <title> and <meta> tags via a side-channel (no VDOM diff). page_title, page_meta
Provides
page_title, page_meta
Pairs with
—
Lets a handler update the document <title> and <meta> tags via a side-channel (no VDOM diff). Just assign self.page_title / self.page_meta. Auto-included on every LiveView.
@event_handler()
def on_new_message(self, **kwargs):
self.unread += 1
self.page_title = f'Chat ({self.unread})'
ActivityMixin
Pre-render hidden UI regions and keep their state when toggled. set_activity_visible()
Provides
set_activity_visible()
Pairs with
{% dj_activity %} tag
Pre-renders hidden UI regions and preserves their local state when toggled (React-19 <Activity> parity), deferring their events until shown. Wrap regions in {% dj_activity %}. Auto-included on every LiveView.
class TabsView(LiveView):
@event_handler()
def show_details(self, **kwargs):
self.set_activity_visible('details', True)
Authentication
Login and permission gatingGate access before any view state is created. LoginRequiredMixin redirects anonymous users at mount time; PermissionRequiredMixin enforces a Django permission — pair them for authenticated, authorized views.
LoginRequiredMixin
Redirect unauthenticated users to login before any state is created. auth check before mount()
Provides
auth check before mount()
Pairs with
settings.LOGIN_URL
Redirects unauthenticated users to login before any view state is created — the WS mount is intercepted, so anonymous users never initialise state. Validates login_url to prevent open redirects. Add explicitly.
from djust.auth import LoginRequiredMixin
class ProtectedView(LoginRequiredMixin, LiveView):
login_url = '/accounts/login/'
template_name = 'protected.html'
PermissionRequiredMixin
Raises PermissionDenied (403) if the user lacks the named Django permission, checked at dispatch time. permission check before mount()
Provides
permission check before mount()
Pairs with
permission_required attribute
Raises PermissionDenied (403) if the user lacks the named Django permission, checked at dispatch time. Pair with LoginRequiredMixin. Add explicitly.
from djust.auth import LoginRequiredMixin, PermissionRequiredMixin
class AdminView(LoginRequiredMixin, PermissionRequiredMixin, LiveView):
permission_required = 'app.change_item'
Integration
Server-side React renderingMixins that bridge djust to other ecosystems — currently ReactMixin, which renders registered React components server-side with client hydration. Add it explicitly when embedding React in a LiveView.
ReactMixin
Renders registered React components server-side with client hydration. render_react_component()
Provides
render_react_component()
Pairs with
React component registry
Renders registered React components server-side with client hydration. Exposes the component registry and render_react_component(name, props) helper. Add explicitly.
from djust.react import ReactMixin
class UIView(ReactMixin, LiveView):
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
ctx['button'] = self.render_react_component('Button', {'label': 'Go'})
return ctx