Home Features Docs Blog Philosophy Examples FAQ Live Demo Hosting
API Reference

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, async

Mixins 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).
# StreamingMixin

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.

Python
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.
# StreamsMixin

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.

Python
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.
# PresenceMixin

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.

Python
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.
# LiveCursorMixin

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.

Python
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.
# NotificationMixin

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.

Python
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.
# AsyncWorkMixin

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.

Python
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, drafts

Mixins 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.
# FormMixin

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.

Python
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.
# WizardMixin

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.

Python
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.
# ModelBindingMixin

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.

Python
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.
# UploadMixin

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.

Python
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.
# DraftModeMixin

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.

Python
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 regions

Mixins 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.
# FlashMixin

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.

Python
@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).
# PageMetadataMixin

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.

Python
@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.
# ActivityMixin

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.

Python
class TabsView(LiveView):
    @event_handler()
    def show_details(self, **kwargs):
        self.set_activity_visible('details', True)

Authentication

Login and permission gating

Gate 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.
# LoginRequiredMixin

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.

Python
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.
# PermissionRequiredMixin

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.

Python
from djust.auth import LoginRequiredMixin, PermissionRequiredMixin

class AdminView(LoginRequiredMixin, PermissionRequiredMixin, LiveView):
    permission_required = 'app.change_item'

Integration

Server-side React rendering

Mixins 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.
# ReactMixin

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.

Python
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