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:
  • request – Reference to current request object.

  • columns – List of column names for the grid. This is optional; if not specified an attempt will be made to deduce the list automatically. See also columns.

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 also render_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() and get_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() and set_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 is None.

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() and is_linked().

sortable

Boolean indicating whether any column sorting is allowed for the grid. Default is False.

See also sort_multiple and sort_on_backend.

sort_multiple

Boolean indicating whether “multi-column” sorting is allowed. Default is True; if this is False 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 and sort_on_backend are true.

See also set_sorter(), sort_defaults and active_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 a SortInfo tuple and must correspond to an entry in sorters.

Used with both frontend and backend sorting.

See also set_sort_defaults() and active_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, and sort_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 and page, and paginate_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 call get_pagesize_options() to get the value.

pagesize

Number of records to show in a data page. See also pagesize_options and page.

Only relevant if paginated is true. If not specified, constructor will call get_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 assume 1 (first page).

searchable_columns

Set of columns declared as searchable for the Vue component.

See also set_searchable() and is_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() and set_tools().

property active_filters

Returns the list of currently active filters.

This inspects each GridFilter in filters and only returns the ones marked active.

add_action(key, **kwargs)[source]

Convenience to add a new GridAction instance to the grid’s actions 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, via get_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 return 20 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 by get_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 records

  • row_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 the row_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 returns False.

For frontend sorting (i.e. sort_on_backend is false), this always returns True.

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 call make_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 and sort_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 call make_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 calls render_datetime() for the return value.

This may be used automatically per set_default_renderers() or you can use it explicitly for any datetime.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 correct form 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 and columns 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 new FieldList 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 if model_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 use render_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 a GridFilter instance, it will be used as-is for the backend filter.

Otherwise make_filter() will be called to obtain the backend filter. The filterinfo will be passed along to that call; if it is empty then key will be used instead.

See also remove_filter(). Backend filters are tracked via filters.

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 via joiners.

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 (if False).

See also get_label(). Label overrides are tracked via labels.

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 via linked_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 from data

  • key is the column name

  • value 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 via searchable_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 and sortdir; 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 and sort_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. The sortinfo will be passed along to that call; if it is empty then key 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() and is_sortable(). Backend sorters are tracked via sorters.

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 its actions list. You can call make_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 calling make_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().

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() and render_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