wuttaweb.grids.base
¶
Base grid classes
- class wuttaweb.grids.base.Grid(request, vue_tagname='wutta-grid', model_class=None, key=None, columns=None, data=None, labels={}, renderers={}, row_class=None, actions=[], linked_columns=[], sortable=False, sort_multiple=True, sort_on_backend=True, sorters=None, sort_defaults=None, paginated=False, paginate_on_backend=True, pagesize_options=None, pagesize=None, page=1, searchable_columns=None, filterable=False, filters=None, filter_defaults=None, joiners=None, tools=None)[source]¶
Base class for all grids.
- Parameters:
Note
Some parameters are not explicitly described above. However their corresponding attributes are described below.
Grid instances contain the following attributes:
- key¶
Presumably unique key for the grid; used to track per-grid sort/filter settings etc.
- vue_tagname¶
String name for Vue component tag. By default this is
'wutta-grid'
. See alsorender_vue_tag()
.
- model_class¶
Model class for the grid, if applicable. When set, this is usually a SQLAlchemy mapped class. This may be used for deriving the default
columns
among other things.
- columns¶
FieldList
instance containing string column names for the grid. Columns will appear in the same order as they are in this list.See also
set_columns()
andget_columns()
.
- data¶
Data set for the grid. This should either be a list of dicts (or objects with dict-like access to fields, corresponding to model records) or else an object capable of producing such a list, e.g. SQLAlchemy query.
This is the “full” data set; see also
get_visible_data()
.
- labels¶
Dict of column label overrides.
See also
get_label()
andset_label()
.
- renderers¶
Dict of column (cell) value renderer overrides.
See also
set_renderer()
.
- row_class¶
This represents the CSS
class
attribute for a row within the grid. Default isNone
.This can be a simple string, in which case the same class is applied to all rows.
Or it can be a callable, which can then return different class(es) depending on each row. The callable must take three args:
(obj, data, i)
- for example:def my_row_class(obj, data, i): if obj.archived: return 'poser-archived' grid = Grid(request, key='foo', row_class=my_row_class)
See
get_row_class()
for more info.
- actions¶
List of
GridAction
instances represenging action links to be shown for each record in the grid.
- linked_columns¶
List of column names for which auto-link behavior should be applied.
See also
set_link()
andis_linked()
.
- sortable¶
Boolean indicating whether any column sorting is allowed for the grid. Default is
False
.See also
sort_multiple
andsort_on_backend
.
- sort_multiple¶
Boolean indicating whether “multi-column” sorting is allowed. Default is
True
; if this isFalse
then only one column may be sorted at a time.Only relevant if
sortable
is true, but applies to both frontend and backend sorting.Warning
This feature is limited by frontend JS capabilities, regardless of
sort_on_backend
value (i.e. for both frontend and backend sorting).In particular, if the app theme templates use Vue 2 + Buefy, then multi-column sorting should work.
But not so with Vue 3 + Oruga, yet - see also the open issue regarding that. For now this flag is simply ignored for Vue 3 + Oruga templates.
Additionally, even with Vue 2 + Buefy this flag can only allow the user to request a multi-column sort. Whereas the “default sort” in the Vue component can only ever be single-column, regardless of
sort_defaults
.
- sort_on_backend¶
Boolean indicating whether the grid data should be sorted on the backend. Default is
True
.If
False
, the client-side Vue component will handle the sorting.Only relevant if
sortable
is also true.
- sorters¶
Dict of functions to use for backend sorting.
Only relevant if both
sortable
andsort_on_backend
are true.See also
set_sorter()
,sort_defaults
andactive_sorters
.
- sort_defaults¶
List of options to be used for default sorting, until the user requests a different sorting method.
This list usually contains either zero or one elements. (More are allowed if
sort_multiple
is true, but see note below.) Each list element is aSortInfo
tuple and must correspond to an entry insorters
.Used with both frontend and backend sorting.
See also
set_sort_defaults()
andactive_sorters
.Warning
While the grid logic is built to handle multi-column sorting, this feature is limited by frontend JS capabilities.
Even if
sort_defaults
contains multiple entries (i.e. for multi-column sorting to be used “by default” for the grid), only the first entry (i.e. single-column sorting) will actually be used as the default for the Vue component.See also
sort_multiple
for more details.
- active_sorters¶
List of sorters currently in effect for the grid; used by
sort_data()
.Whereas
sorters
defines all “available” sorters, andsort_defaults
defines the “default” sorters,active_sorters
defines the “current/effective” sorters.This attribute is set by
load_settings()
; until that is called it will not exist.This is conceptually a “subset” of
sorters
although a different format is used here:grid.active_sorters = [ {'key': 'name', 'dir': 'asc'}, {'key': 'id', 'dir': 'asc'}, ]
The above is for example only; there is usually no reason to set this attribute directly.
This list may contain multiple elements only if
sort_multiple
is true. Otherewise it should always have either zero or one element.
- paginated¶
Boolean indicating whether the grid data should be paginated, i.e. split up into pages. Default is
False
which means all data is shown at once.See also
pagesize
andpage
, andpaginate_on_backend
.
- paginate_on_backend¶
Boolean indicating whether the grid data should be paginated on the backend. Default is
True
which means only one “page” of data is sent to the client-side component.If this is
False
, the full set of grid data is sent for each request, and the client-side Vue component will handle the pagination.Only relevant if
paginated
is also true.
- pagesize_options¶
List of “page size” options for the grid. See also
pagesize
.Only relevant if
paginated
is true. If not specified, constructor will callget_pagesize_options()
to get the value.
- pagesize¶
Number of records to show in a data page. See also
pagesize_options
andpage
.Only relevant if
paginated
is true. If not specified, constructor will callget_pagesize()
to get the value.
- page¶
The current page number (of data) to display in the grid. See also
pagesize
.Only relevant if
paginated
is true. If not specified, constructor will assume1
(first page).
- searchable_columns¶
Set of columns declared as searchable for the Vue component.
See also
set_searchable()
andis_searchable()
.
- filterable¶
Boolean indicating whether the grid should show a “filters” section where user can filter data in various ways. Default is
False
.
- filters¶
Dict of
GridFilter
instances available for use with backend filtering.Only relevant if
filterable
is true.See also
set_filter()
.
- filter_defaults¶
Dict containing default state preferences for the filters.
See also
set_filter_defaults()
.
- joiners¶
Dict of “joiner” functions for use with backend filtering and sorting.
See
set_joiner()
for more info.
- tools¶
Dict of “tool” elements for the grid. Tools are usually buttons (e.g. “Delete Results”), shown on top right of the grid.
The keys for this dict are somewhat arbitrary, defined by the caller. Values should be HTML literal elements.
See also
add_tool()
andset_tools()
.
- property active_filters¶
Returns the list of currently active filters.
This inspects each
GridFilter
infilters
and only returns the ones marked active.
- add_action(key, **kwargs)[source]¶
Convenience to add a new
GridAction
instance to the grid’sactions
list.
- add_tool(html, key=None)[source]¶
Add a new HTML snippet to the
tools
dict.- Parameters:
html – HTML literal for the tool element.
key – Optional key to use when adding to the
tools
dict. If not specified, a random string is generated.
See also
set_tools()
.
- append(*keys)[source]¶
Add some columns(s) to the grid.
This is a convenience to allow adding multiple columns at once:
grid.append('first_field', 'second_field', 'third_field')
It will add each column to
columns
.
- filter_data(data, filters=None)[source]¶
Filter the given data and return the result. This is called by
get_visible_data()
.- Parameters:
filters – Optional list of filters to use. If not specified, the grid’s
active_filters
are used.
- get_columns()[source]¶
Returns the official list of column names for the grid, or
None
.If
columns
is set and non-empty, it is returned.Or, if
model_class
is set, the field list is derived from that, viaget_model_columns()
.Otherwise
None
is returned.
- get_label(key)[source]¶
Returns the label text for a given column.
If no override is defined, the label is derived from
key
.See also
set_label()
.
- get_model_columns(model_class=None)[source]¶
This method is a shortcut which calls
get_model_fields()
.- Parameters:
model_class – Optional model class for which to return fields. If not set, the grid’s
model_class
is assumed.
- get_pagesize(default=None)[source]¶
Returns the default page size for the grid.
It will check config but if no setting exists, will fall back to a value from
pagesize_options
(will return20
if that is listed; otherwise the “first” option).- Parameters:
default – Alternate default value to return if none is configured.
This method is intended for use in the constructor. Code can instead access
pagesize
directly.
- get_pagesize_options(default=None)[source]¶
Returns a list of default page size options for the grid.
It will check config but if no setting exists, will fall back to:
[5, 10, 20, 50, 100, 200]
- Parameters:
default – Alternate default value to return if none is configured.
This method is intended for use in the constructor. Code can instead access
pagesize_options
directly.
- get_row_class(obj, data, i)[source]¶
Returns the row CSS
class
attribute for the given record. This method is called byget_vue_context()
.This will inspect/invoke
row_class
and return the value obtained from there.- Parameters:
obj – Reference to the original model instance.
data – Dict of record data for the instance; part of the Vue grid data set in/from
get_vue_context()
.i – One-based sequence for this object/record (row) within the grid.
- Returns:
String of CSS class name(s), or
None
.
- get_visible_data()[source]¶
Returns the “effective” visible data for the grid.
This uses
data
as the starting point but may morph it for pagination etc. per the grid settings.Code can either access
data
directly, or call this method to get only the data for current view (e.g. assuming pagination is used), depending on the need.See also these methods which may be called by this one:
- get_vue_active_sorters()[source]¶
Returns a list of Vue-compatible column sorter definitions.
The list returned is the same as
active_sorters
; however the format used in Vue is different. So this method just “converts” them to the required format, e.g.:# active_sorters format {'key': 'name', 'dir': 'asc'} # get_vue_active_sorters() format {'field': 'name', 'order': 'asc'}
- Returns:
The
active_sorters
list, converted as described above.
- get_vue_columns()[source]¶
Returns a list of Vue-compatible column definitions.
This uses
columns
as the basis; each definition returned will be a dict in this format:{ 'field': 'foo', 'label': "Foo", 'sortable': True, 'searchable': False, }
The full format is determined by Buefy; see the Column section in its Table docs.
See also
get_vue_context()
.
- get_vue_context()[source]¶
Returns a dict of context for the grid, for use with the Vue component. This contains the following keys:
data
- list of Vue-compatible data recordsrow_classes
- dict of per-row CSS classes
This first calls
get_visible_data()
to get the original data set. Each record is converted to a dict.Then it calls
make_json_safe()
to ensure each record can be serialized to JSON.Then it invokes any
renderers
which are defined, to obtain the “final” values for each record.Then it adds a URL key/value for each of the
actions
defined, to each record.Then it calls
get_row_class()
for each record. If a value is returned, it is added to therow_classes
dict. Note that this dict is keyed by “zero-based row sequence as string” - the Vue component expects that.- Returns:
Dict of grid data/CSS context as described above.
- get_vue_filters()[source]¶
Returns a list of Vue-compatible filter definitions.
This returns the full set of
filters
but represents each as a simple dict with the filter state.
- get_vue_pager_stats()[source]¶
Returns a simple dict with current grid pager stats.
This is used when
paginate_on_backend
is in effect.
- is_linked(key)[source]¶
Returns boolean indicating if auto-link behavior is enabled for a given column.
See also
set_link()
which describes auto-link behavior.- Parameters:
key – Column key as string.
- is_searchable(key)[source]¶
Check if the given column is marked as searchable for the Vue component.
See also
set_searchable()
.
- is_sortable(key)[source]¶
Returns boolean indicating if a given column should allow sorting.
If
sortable
is false, this always returnsFalse
.For frontend sorting (i.e.
sort_on_backend
is false), this always returnsTrue
.For backend sorting, may return true or false depending on whether the column is listed in
sorters
.- Parameters:
key – Column key as string.
See also
set_sorter()
.
- load_settings(persist=True)[source]¶
Load all effective settings for the grid.
If the request GET params (query string) contains grid settings, they are used; otherwise the settings are loaded from user session.
Note
As of now, “sorting” and “pagination” settings are the only type supported by this logic. Settings for “filtering” coming soon…
The overall logic for this method is as follows:
collect settings
apply settings to current grid
optionally save settings to user session
Saving the settings to user session will allow the grid to remember its current settings when user refreshes the page, or navigates away then comes back. Therefore normally, settings are saved each time they are loaded. Note that such settings are wiped upon user logout.
- Parameters:
persist – Whether the collected settings should be saved to the user session.
- make_backend_filters(filters=None)[source]¶
Make backend filters for all columns in the grid.
This is called by the constructor, if
filterable
is true.For each column in the grid, this checks the provided
filters
and if the column is not yet in there, will callmake_filter()
to add it.Note
This only works if grid has a
model_class
. If not, this method just returns the initial filters (or empty dict).- Parameters:
filters – Optional dict of initial filters. Any existing filters will be left intact, not replaced.
- Returns:
Final dict of all filters. Includes any from the initial
filters
param as well as any which were created.
- make_backend_sorters(sorters=None)[source]¶
Make backend sorters for all columns in the grid.
This is called by the constructor, if both
sortable
andsort_on_backend
are true.For each column in the grid, this checks the provided
sorters
and if the column is not yet in there, will callmake_sorter()
to add it.Note
This only works if grid has a
model_class
. If not, this method just returns the initial sorters (or empty dict).- Parameters:
sorters – Optional dict of initial sorters. Any existing sorters will be left intact, not replaced.
- Returns:
Final dict of all sorters. Includes any from the initial
sorters
param as well as any which were created.
- make_filter(columninfo, **kwargs)[source]¶
Create and return a
GridFilter
instance suitable for use on the given column.Code usually does not need to call this directly. See also
set_filter()
, which calls this method automatically.- Parameters:
columninfo – Can be either a model property (see below), or a column name.
- Returns:
A
GridFilter
instance.
- make_sorter(columninfo, keyfunc=None, foldcase=True)[source]¶
Returns a function suitable for use as a backend sorter on the given column.
Code usually does not need to call this directly. See also
set_sorter()
, which calls this method automatically.- Parameters:
columninfo – Can be either a model property (see below), or a column name.
keyfunc – Optional function to use as the “sort key getter” callable, if the sorter is manual (as opposed to SQLAlchemy query). More on this below. If not specified, a default function is used.
foldcase – If the sorter is manual (not SQLAlchemy), and the column data is of text type, this may be used to automatically “fold case” for the sorting. Defaults to
True
since this behavior is presumably expected, but may be disabled if needed.
The term “model property” is a bit technical, an example should help to clarify:
model = app.model grid = Grid(request, model_class=model.Person) # explicit property sorter = grid.make_sorter(model.Person.full_name) # property name works if grid has model class sorter = grid.make_sorter('full_name') # nb. this will *not* work person = model.Person(full_name="John Doe") sorter = grid.make_sorter(person.full_name)
The
keyfunc
param allows you to override the way sort keys are obtained from data records (this only applies for a “manual” sort, where data is a list and not a SQLAlchemy query):data = [ {'foo': 1}, {'bar': 2}, ] # nb. no model_class, just as an example grid = Grid(request, columns=['foo', 'bar'], data=data) def getkey(obj): if obj.get('foo') return obj['foo'] if obj.get('bar'): return obj['bar'] return '' # nb. sortfunc will ostensibly sort by 'foo' column, but in # practice it is sorted per value from getkey() above sortfunc = grid.make_sorter('foo', keyfunc=getkey) sorted_data = sortfunc(data, 'asc')
- Returns:
A function suitable for backend sorting. This function will behave differently when it is given a SQLAlchemy query vs. a “list” of data. In either case it will return the sorted result.
This function may be called as shown above. It expects 2 args:
(data, direction)
- paginate_data(data)[source]¶
Apply pagination to the given data set, based on grid settings.
This returns a “pager” object which can then be used as a “data replacement” in subsequent logic.
This method is called by
get_visible_data()
.
- remove(*keys)[source]¶
Remove some column(s) from the grid.
This is a convenience to allow removal of multiple columns at once:
grid.remove('first_field', 'second_field', 'third_field')
It will remove each column from
columns
.
- remove_filter(key)[source]¶
Remove the backend filter for a column.
This removes the filter instance, so there is no way to filter by this column unless another filter is later defined for it.
See also
set_filter()
.
- remove_joiner(key)[source]¶
Remove the backend joiner for a column.
Note that this removes the joiner function, so there is no way to apply joins for this column unless another joiner is later defined for it.
See also
set_joiner()
.
- remove_sorter(key)[source]¶
Remove the backend sorter for a column.
Note that this removes the sorter function, so there is no way to sort by this column unless another sorter is later defined for it.
See also
set_sorter()
.
- render_datetime(obj, key, value)[source]¶
Default cell value renderer for
sqlalchemy.types.DateTime
columns, which callsrender_datetime()
for the return value.This may be used automatically per
set_default_renderers()
or you can use it explicitly for anydatetime.datetime
column with:grid.set_renderer('foo', grid.render_datetime)
- render_table_element(form=None, template='/grids/table_element.mako', **context)[source]¶
Render a simple Vue table element for the grid.
This is what you want for a “simple” grid which does require a unique Vue component, but can instead use the standard table component.
This returns something like:
<b-table :data="gridContext['mykey'].data"> <!-- columns etc. --> </b-table>
See
render_vue_template()
for a more complete variant.Actual output will of course depend on grid attributes,
key
,columns
etc.- Parameters:
form – Reference to the
Form
instance which “contains” this grid. This is needed in order to ensure the grid data is available to the form Vue component.template – Path to Mako template which is used to render the output.
Note
The above example shows
gridContext['mykey'].data
as the Vue data reference. This should “just work” if you provide the correctform
arg and the grid is contained directly by that form’s Vue component.However, this may not account for all use cases. For now we wait and see what comes up, but know the dust may not yet be settled here.
- render_vue_finalize()[source]¶
Render the Vue “finalize” script for the grid.
By default this simply returns:
<script> WuttaGrid.data = function() { return WuttaGridData } Vue.component('wutta-grid', WuttaGrid) </script>
The actual output may depend on various grid attributes, in particular
vue_tagname
.
- render_vue_tag(**kwargs)[source]¶
Render the Vue component tag for the grid.
By default this simply returns:
<wutta-grid></wutta-grid>
The actual output will depend on various grid attributes, in particular
vue_tagname
.
- render_vue_template(template='/grids/vue_template.mako', **context)[source]¶
Render the Vue template block for the grid.
This is what you want for a “full-featured” grid which will exist as its own unique Vue component on the frontend.
This returns something like:
<script type="text/x-template" id="wutta-grid-template"> <b-table> <!-- columns etc. --> </b-table> </script> <script> WuttaGridData = {} WuttaGrid = { template: 'wutta-grid-template', } </script>
See
render_table_element()
for a simpler variant.Actual output will of course depend on grid attributes,
vue_tagname
andcolumns
etc.- Parameters:
template – Path to Mako template which is used to render the output.
- set_columns(columns)[source]¶
Explicitly set the list of grid columns.
This will overwrite
columns
with a newFieldList
instance.- Parameters:
columns – List of string column names.
- set_default_renderers()[source]¶
Set default column value renderers, where applicable.
This will add new entries to
renderers
for columns whose data type implies a default renderer should be used. This is generally only possible ifmodel_class
is set to a valid SQLAlchemy mapped class.This (for now?) only looks for
sqlalchemy.types.DateTime
columns and if any are found, they are configured to userender_datetime()
.
- set_filter(key, filterinfo=None, **kwargs)[source]¶
Set/override the backend filter for a column.
Only relevant if
filterable
is true.- Parameters:
key – Name of column.
filterinfo – Can be either a
GridFilter
instance, or else a model property (see below).
If
filterinfo
is aGridFilter
instance, it will be used as-is for the backend filter.Otherwise
make_filter()
will be called to obtain the backend filter. Thefilterinfo
will be passed along to that call; if it is empty thenkey
will be used instead.See also
remove_filter()
. Backend filters are tracked viafilters
.
- set_filter_defaults(**defaults)[source]¶
Set default state preferences for the grid filters.
These preferences will affect the initial grid display, until user requests a different filtering method.
Each kwarg should be named by filter key, and the value should be a dict of preferences for that filter. For instance:
grid.set_filter_defaults(name={'active': True, 'verb': 'contains', 'value': 'foo'}, value={'active': True})
Filter defaults are tracked via
filter_defaults
.
- set_joiner(key, joiner)[source]¶
Set/override the backend joiner for a column.
A “joiner” is sometimes needed when a column with “related but not primary” data is involved in a sort or filter operation.
A sorter or filter may need to “join” other table(s) to get at the appropriate data. But if a given column has both a sorter and filter defined, and both are used at the same time, we don’t want the join to happen twice.
Hence we track joiners separately, also keyed by column name (as are sorters and filters). When a column’s sorter and/or filter is needed, the joiner will be invoked.
- Parameters:
key – Name of column.
joiner – A joiner callable, as described below.
A joiner callable must accept just one
(data)
arg and return the “joined” data/query, for example:model = app.model grid = Grid(request, model_class=model.Person) def join_external_profile_value(query): return query.join(model.ExternalProfile) def sort_external_profile(query, direction): sortspec = getattr(model.ExternalProfile.description, direction) return query.order_by(sortspec()) grid.set_joiner('external_profile', join_external_profile) grid.set_sorter('external_profile', sort_external_profile)
See also
remove_joiner()
. Backend joiners are tracked viajoiners
.
- set_label(key, label, column_only=False)[source]¶
Set/override the label for a column.
- Parameters:
key – Name of column.
label – New label for the column header.
column_only – Boolean indicating whether the label should be applied only to the column header (if
True
), vs. applying also to the filter (ifFalse
).
See also
get_label()
. Label overrides are tracked vialabels
.
- set_link(key, link=True)[source]¶
Explicitly enable or disable auto-link behavior for a given column.
If a column has auto-link enabled, then each of its cell contents will automatically be wrapped with a hyperlink. The URL for this will be the same as for the “View”
GridAction
(aka.view()
). Although of course each cell in the column gets a different link depending on which data record it points to.It is typical to enable auto-link for fields relating to ID, description etc. or some may prefer to auto-link all columns.
See also
is_linked()
; the list is tracked vialinked_columns
.- Parameters:
key – Column key as string.
link – Boolean indicating whether column’s cell contents should be auto-linked.
- set_renderer(key, renderer, **kwargs)[source]¶
Set/override the value renderer for a column.
- Parameters:
key – Name of column.
renderer – Callable as described below.
Depending on the nature of grid data, sometimes a cell’s “as-is” value will be undesirable for display purposes.
The logic in
get_vue_context()
will first “convert” all grid data as necessary so that it is at least JSON-compatible.But then it also will invoke a renderer override (if defined) to obtain the “final” cell value.
A renderer must be a callable which accepts 3 args
(record, key, value)
:record
is the “original” record fromdata
key
is the column namevalue
is the JSON-safe cell value
Whatever the renderer returns, is then used as final cell value. For instance:
from webhelpers2.html import HTML def render_foo(record, key, value): return HTML.literal("<p>this is the final cell value</p>") grid = Grid(request, columns=['foo', 'bar']) grid.set_renderer('foo', render_foo)
Renderer overrides are tracked via
renderers
.
- set_searchable(key, searchable=True)[source]¶
(Un)set the given column’s searchable flag for the Vue component.
See also
is_searchable()
. Flags are tracked viasearchable_columns
.
- set_sort_defaults(*args)[source]¶
Set the default sorting method for the grid. This sorting is used unless/until the user requests a different sorting method.
args
for this method are interpreted as follows:If 2 args are received, they should be for
sortkey
andsortdir
; for instance:grid.set_sort_defaults('name', 'asc')
If just one 2-tuple arg is received, it is handled similarly:
grid.set_sort_defaults(('name', 'asc'))
If just one string arg is received, the default
sortdir
is assumed:grid.set_sort_defaults('name') # assumes 'asc'
Otherwise there should be just one list arg, elements of which are each 2-tuples of
(sortkey, sortdir)
info:grid.set_sort_defaults([('name', 'asc'), ('value', 'desc')])
Note
Note that
sort_multiple
determines whether the grid is actually allowed to have multiple sort defaults. The defaults requested by the method call may be pruned if necessary to accommodate that.Default sorting info is tracked via
sort_defaults
.
- set_sorter(key, sortinfo=None)[source]¶
Set/override the backend sorter for a column.
Only relevant if both
sortable
andsort_on_backend
are true.- Parameters:
key – Name of column.
sortinfo – Can be either a sorter callable, or else a model property (see below).
If
sortinfo
is a callable, it will be used as-is for the backend sorter.Otherwise
make_sorter()
will be called to obtain the backend sorter. Thesortinfo
will be passed along to that call; if it is empty thenkey
will be used instead.A backend sorter callable must accept
(data, direction)
args and return the sorted data/query, for example:model = app.model grid = Grid(request, model_class=model.Person) def sort_full_name(query, direction): sortspec = getattr(model.Person.full_name, direction) return query.order_by(sortspec()) grid.set_sorter('full_name', sort_full_name)
See also
remove_sorter()
andis_sortable()
. Backend sorters are tracked viasorters
.
- set_tools(tools)[source]¶
Set the
tools
attribute using the given tools collection.This will normalize the list/dict to desired internal format.
- sort_data(data, sorters=None)[source]¶
Sort the given data and return the result. This is called by
get_visible_data()
.- Parameters:
sorters – Optional list of sorters to use. If not specified, the grid’s
active_sorters
are used.
- property vue_component¶
String name for the Vue component, e.g.
'WuttaGrid'
.This is a generated value based on
vue_tagname
.
- class wuttaweb.grids.base.GridAction(request, key, label=None, url=None, icon=None, link_class=None)[source]¶
Represents a “row action” hyperlink within a grid context.
All such actions are displayed as a group, in a dedicated Actions column in the grid. So each row in the grid has its own set of action links.
A
Grid
can have one (or zero) or more of these in itsactions
list. You can callmake_grid_action()
to add custom actions from within a view.- Parameters:
request – Current request object.
Note
Some parameters are not explicitly described above. However their corresponding attributes are described below.
- key¶
String key for the action (e.g.
'edit'
), unique within the grid.
- label¶
Label to be displayed for the action link. If not set, will be generated from
key
by callingmake_title()
.See also
render_label()
.
- url¶
URL for the action link, if applicable. This can be a simple string, however that will cause every row in the grid to have the same URL for this action.
A better way is to specify a callable which can return a unique URL for each record. The callable should expect
(obj, i)
args, for instance:def myurl(obj, i): return request.route_url('widgets.view', uuid=obj.uuid) action = GridAction(request, 'view', url=myurl)
See also
get_url()
.
- icon¶
Name of icon to be shown for the action link.
See also
render_icon()
.
- link_class¶
Optional HTML class attribute for the action’s
<a>
tag.
- get_url(obj, i=None)[source]¶
Returns the action link URL for the given object (model instance).
If
url
is a simple string, it is returned as-is.But if
url
is a callable (which is typically the most useful), that will be called with the same(obj, i)
args passed along.- Parameters:
obj – Model instance of whatever type the parent grid is setup to use.
i – One-based sequence for the object’s row within the parent grid.
See also
url
.
- render_icon()[source]¶
Render the HTML snippet for the action link icon.
This uses
icon
to identify the named icon to be shown. Output is something like (here'trash'
is the icon name):<i class="fas fa-trash"></i>
See also
render_icon_and_label()
.
- render_icon_and_label()[source]¶
Render the HTML snippet for action link icon and label.
Default logic returns the output from
render_icon()
andrender_label()
.
- render_label()[source]¶
Render the label text for the action link.
Default behavior is to return
label
as-is.See also
render_icon_and_label()
.
- class wuttaweb.grids.base.SortInfo(sortkey, sortdir)¶
Named tuple to track sorting info.
Elements of
sort_defaults
will be of this type.- sortdir¶
Alias for field number 1
- sortkey¶
Alias for field number 0