Table
Table shows one row per kept event, with server-side pagination and a button per row for each of its actions.
import dachshund
from dachshund.widgets import Table
with dachshund.row():
dachshund.add(Table("sessions", columns=["user", "ip"], key="user"))
dachshund.emit("sessions", user="ada", ip="10.0.0.1")
dachshund.widgets.table.table.Table
dataclass
Table(name, *, source='', title=None, actions=list(), action_args=dict(), persist=False, columns, key=None, page_size=10, loader=None, search=True, sortable=None)
Bases: KeyedWidget
A searchable, sortable table, one row per kept event.
Example
with dachshund.row():
dachshund.add(Table("sessions", columns=["user", "ip"], key="user"))
dachshund.emit("sessions", user="ada", ip="10.0.0.1")
Options
columns(list[str]) - The payload fields shown, left to right. Required.key(str) - The field identifying a row across events. An event whose key matches a kept row replaces it. Defaults toNone, every event is a new row.page_size(int) - Rows per page. Defaults to10.search(bool) - Shows a search box. Defaults toTrue.sortable(list[str]) - Columns sorted by clicking their header. Defaults to every shown column.loader(Loader) - Fetches rows from data dachshund doesn't own, see Loader. Defaults toNone.persist(bool) - Keeps rows across restarts. Needskeyand the dashboard'sstorage. Can't be combined withloader. Defaults toFalse.actions(list[str]) - Actions shown as a button on every row. Defaults to[].
source, title and action_args are common to every widget, see
Widget.
Row fields
A field starting with _ is hidden from the table and passed to the
row's actions without the underscore:
@dachshund.action("ban", label="Ban", confirm=True)
def ban(ctx, user: str, team_id: str) -> None: ...
with dachshund.row():
dachshund.add(Table("sessions", columns=["user"], key="user", actions=["ban"]))
dachshund.emit("sessions", user="ada", _team_id="42")
A truthy _delete field removes the row with that key.
Loader
A function of (ctx, query), sync or async, returning (rows, total).
query is a TableQuery: apply its search, sort,
offset and limit, and return that page. total is the number of rows
matching the search, or None when counting them is too costly. It's
called every time a page is shown.
def load_users(ctx, query):
users = ctx["db"].users(search=query.search, order_by=query.sort_by)
page = users[query.offset : query.offset + query.limit]
return page, len(users)
with dachshund.row():
dachshund.add(Table("users", columns=["name", "email"], loader=load_users))
Pagination
Pages move by offset, showing "11-20 of 412". Without a total, the next page is offered while a full page comes back. A live update refreshes the page shown, so rows can shift across pages as they change.
columns
instance-attribute
columns
key
class-attribute
instance-attribute
key = None
page_size
class-attribute
instance-attribute
page_size = 10
loader
class-attribute
instance-attribute
loader = None
search
class-attribute
instance-attribute
search = True
sortable
class-attribute
instance-attribute
sortable = field(default=None)
type
class-attribute
type = 'table'
op
class-attribute
op = 'replace'
renders_own_actions
class-attribute
renders_own_actions = True
paginated
class-attribute
paginated = True
script
class-attribute
script = Path(__file__).parent / 'table.js'
style
class-attribute
style = Path(__file__).parent / 'table.css'
shown
property
shown
The columns drawn, hidden _ ones left out.
sortable_columns
property
sortable_columns
The columns whose header sorts the table.
render
render(events)
Rebuild every row from the events kept for this source.
An event carrying key replaces the row it matches; one that
doesn't, or carries no value for it, is always its own row.
A persisting table reads its own kept rows instead, since those cover more than whatever events are still around to rebuild from.
Source code in dachshund/widgets/table/table.py
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | |
query
query(rows, query)
rows matching query's search, in its order. No page is cut.
Source code in dachshund/widgets/table/table.py
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | |
page
async
page(events, query, context, host_loop=None)
One page of this table's rows, as query asks for.
A loader answers directly, sync or async; see run().
Source code in dachshund/widgets/table/table.py
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 | |
accumulate
accumulate(event)
Fold one more event into the kept rows.
A truthy _delete removes the row instead of updating it.
Source code in dachshund/widgets/table/table.py
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 | |
dachshund.widgets.query.TableQuery
dataclass
TableQuery(search=None, sort_by=None, descending=False, offset=0, limit=None, levels=frozenset())
What a table asks of its rows: a search, a sort and a page.
Options
search(str) - Text typed in the search box. Defaults toNone.sort_by(str) - The column sorted by. Defaults toNone, unsorted.descending(bool) - Sorts highest first. Defaults toFalse.offset(int) - Rows skipped before the page. Defaults to0.limit(int) - Rows in the page. Defaults toNone, the table'spage_size.levels(frozenset[int]) - The log levels aLogswidget shows. Defaults to empty, every level it captures.
search
class-attribute
instance-attribute
search = None
sort_by
class-attribute
instance-attribute
sort_by = None
descending
class-attribute
instance-attribute
descending = False
offset
class-attribute
instance-attribute
offset = 0
limit
class-attribute
instance-attribute
limit = None
levels
class-attribute
instance-attribute
levels = frozenset()