LiveView
On this page
The LiveView class is the core building block of djust. It combines a Django class-based view with a persistent WebSocket session that keeps state on the server.
Basic Structure
from djust import LiveView
from djust.decorators import event_handler
class MyView(LiveView):
template_name = "myapp/my_view.html"
def mount(self, request, **kwargs):
"""Initialize state. Public attributes reach the template automatically."""
self.count = 0
self.items = []
@event_handler()
def increment(self, **kwargs):
"""Handle a dj-click="increment" event."""
self.count += 1
Lifecycle Hooks
mount(request, **kwargs)
Called when the LiveView is first rendered over HTTP, and again when the WebSocket connects (unless state is restored from a snapshot). Keep it idempotent — no one-time side effects. Use this to:
- Initialize state variables
- Read URL parameters from
**kwargs - Fetch initial data from the database
def mount(self, request, **kwargs):
item_id = kwargs.get("item_id")
self.item = Item.objects.get(pk=item_id)
self.editing = False
After mount(), every state change triggers a re-render automatically.
get_context_data(**kwargs)
Called before every render — both the initial HTTP render and every WebSocket update. Returns the template context dictionary.
Always call super().get_context_data(**kwargs) to include djust's required context:
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update({
"items": self.items,
"count": self.count,
})
return context
handle_params(params, uri)
Called after mount() on the initial render, and again on every URL change (live_patch(), browser back/forward) without a full page reload. Use it to derive state from query params:
def handle_params(self, params, uri):
self.page = int(params.get("page", 1))
self._refresh()
handle_info(message)
Called with out-of-band messages delivered to the view. Currently these are PostgreSQL NOTIFY events for views that subscribe with self.listen(channel) (NotificationMixin). The single argument is a dict:
def handle_info(self, message):
if message["type"] == "db_notify":
self.refresh()
State Management
State lives on self. Any public attribute (self.count) is:
- Included in the template context
- Preserved across WebSocket events
- Re-rendered when changed
Private attributes (prefixed with _) are kept out of the template context and never sent to the client. Those set in mount() are still saved with the view's server-side state when they are JSON-serializable (models are stored as refs). Other values, such as QuerySets, are dropped on restore, so re-derive them rather than caching them in _ attributes:
def mount(self, request, **kwargs):
self._db_items = Item.objects.all() # private — not in the template, not restored
self.count = self._db_items.count() # public — available in template
Inline Templates
For simple views, use template instead of template_name:
class HelloView(LiveView):
template = "<h1>Hello {{ name }}!</h1>"
def mount(self, request, **kwargs):
self.name = "World"
URL Configuration
LiveViews use Django's standard as_view():
from django.urls import path
from myapp.views import MyView
urlpatterns = [
path("items/<int:item_id>/", MyView.as_view(), name="my-view"),
]
Authentication
Use Django's built-in mixins:
from django.contrib.auth.mixins import LoginRequiredMixin
from djust import LiveView
class ProtectedView(LoginRequiredMixin, LiveView):
template_name = "myapp/protected.html"
login_url = "/login/"
Or use djust's permission decorator on individual handlers:
from djust.decorators import event_handler, permission_required
@event_handler()
@permission_required("myapp.can_delete")
def delete_item(self, item_id: int = 0, **kwargs):
Item.objects.filter(pk=item_id).delete()
HTTP Fallback Mode
If the WebSocket is unavailable (for example, behind a proxy that blocks it), client.js sends each event as a JSON POST to the view's URL and applies the returned patches. JavaScript is still required. The initial GET is always a complete server-rendered page, which is what crawlers see.
Next Steps
- Events — event binding and handler patterns
- Components — reusable UI components
- Templates — template directives reference
- Loading States & Background Work — spinners, async operations