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
#CustomerTotal ($)StatusCreated
8Tyrell Corp159.92shipped2026-05-03T04:30:19.245807+00:00
7Cyberdyne139.93pending2026-05-03T04:30:19.241671+00:00
6Stark Industries119.94cancelled2026-05-03T04:30:19.237295+00:00
5Wayne Ent.99.95shipped2026-05-03T04:30:19.233358+00:00
4Umbrella Co79.96pending2026-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

#CustomerTotal ($)StatusCreated
8Tyrell Corp159.92shipped2026-05-03T04:30:19.245807+00:00
7Cyberdyne139.93pending2026-05-03T04:30:19.241671+00:00
6Stark Industries119.94cancelled2026-05-03T04:30:19.237295+00:00
5Wayne Ent.99.95shipped2026-05-03T04:30:19.233358+00:00
4Umbrella Co79.96pending2026-05-03T04:30:19.224903+00:00
template tag emits the <table> with click-to-sort handlers wired to those events. No per-view handler boilerplate.