DataTableMixin — sortable, filterable, paginated grid
Backed by the realtime.Order model from PR #1. Click a column header to sort. Use the search box to filter. Prev/next to page. All wired automatically by the mixin.
Orders
DataTableMixin| # | Customer | Total ($) | Status | Created |
|---|---|---|---|---|
| 8 | Tyrell Corp | 159.92 | shipped | 2026-05-03T04:30:19.245807+00:00 |
| 7 | Cyberdyne | 139.93 | pending | 2026-05-03T04:30:19.241671+00:00 |
| 6 | Stark Industries | 119.94 | cancelled | 2026-05-03T04:30:19.237295+00:00 |
| 5 | Wayne Ent. | 99.95 | shipped | 2026-05-03T04:30:19.233358+00:00 |
| 4 | Umbrella Co | 79.96 | pending | 2026-05-03T04:30:19.224903+00:00 |
The whole pattern
from djust.components.mixins.data_table import DataTableMixin
class OrderDataTableView(DataTableMixin, LiveView):
table_model = Order
table_columns = [
{'key': 'customer', 'label': 'Customer', 'sortable': True, 'filterable': True},
{'key': 'total', 'label': 'Total', 'sortable': True},
{'key': 'status', 'label': 'Status', 'sortable': True, 'filterable': True},
]
table_page_size = 25
table_default_sort = '-created_at'
def mount(self, request, **kwargs):
super().mount(request, **kwargs)
self.init_table_state()
self.refresh_table()
The mixin auto-decorates on_table_sort / on_table_page /
on_table_filter with @event_handler(). The
template tag emits
the <table> with click-to-sort handlers wired to those events. No per-view
handler boilerplate.
# Customer Total ($) Status Created 8 Tyrell Corp 159.92 shipped 2026-05-03T04:30:19.245807+00:00 7 Cyberdyne 139.93 pending 2026-05-03T04:30:19.241671+00:00 6 Stark Industries 119.94 cancelled 2026-05-03T04:30:19.237295+00:00 5 Wayne Ent. 99.95 shipped 2026-05-03T04:30:19.233358+00:00 4 Umbrella Co 79.96 pending 2026-05-03T04:30:19.224903+00:00