pub trait ModelAdmin: AdminModel {
// Provided methods
fn list_display() -> &'static [&'static str] { ... }
fn list_filter() -> &'static [&'static str] { ... }
fn search_fields() -> &'static [&'static str] { ... }
fn ordering() -> &'static [&'static str] { ... }
fn list_per_page() -> usize { ... }
fn readonly_fields() -> &'static [&'static str] { ... }
fn fieldsets() -> &'static [Fieldset] { ... }
fn bulk_actions() -> &'static [BulkAction] { ... }
fn execute_bulk_action<'a>(
action: &'a str,
_ids: &'a [i64],
_db: &'a Db,
_ctx: &'a BulkActionContext<'a>,
) -> Pin<Box<dyn Future<Output = Result<BulkActionResult>> + Send + 'a>> { ... }
}Expand description
Django-style customisation surface for a registered admin model.
Every type that implements AdminModel gets a default impl via
the blanket below. Override the methods you care about; everything
else inherits sensible defaults.
Provided Methods§
Sourcefn list_display() -> &'static [&'static str]
fn list_display() -> &'static [&'static str]
Columns shown on the list page, in order. Default: every
field declared on AdminModel::FIELDS.
Returning &[] means “use the model’s full field list” — the
list page expands the empty default into M::FIELDS. Any
non-empty slice replaces the defaults verbatim.
Sourcefn list_filter() -> &'static [&'static str]
fn list_filter() -> &'static [&'static str]
Columns offered as filter chips in the sidebar. Default: none.
Sourcefn search_fields() -> &'static [&'static str]
fn search_fields() -> &'static [&'static str]
Columns searched by the list-page search box (case-insensitive substring match). Default: none.
Sourcefn ordering() -> &'static [&'static str]
fn ordering() -> &'static [&'static str]
Default ordering. -foo for foo DESC, foo for foo ASC.
Multiple entries → multi-column ORDER BY in slice order.
Default: ["-id"] (newest first).
Sourcefn list_per_page() -> usize
fn list_per_page() -> usize
Rows per page on the list view. Default: 50.
Sourcefn readonly_fields() -> &'static [&'static str]
fn readonly_fields() -> &'static [&'static str]
Read-only fields on the change form. Default: none.
Sourcefn fieldsets() -> &'static [Fieldset]
fn fieldsets() -> &'static [Fieldset]
Field grouping on the change form. Default: empty — fall back
to the framework heuristic (Default / System / Advanced).
Sourcefn bulk_actions() -> &'static [BulkAction]
fn bulk_actions() -> &'static [BulkAction]
Custom bulk actions surfaced as extra buttons in the list-view bulk bar (next to the framework’s built-in Delete). Default: none.
BulkAction is metadata only — pair this method with an
ModelAdmin::execute_bulk_action override that matches on
name and applies the work. The framework’s default
dispatcher returns a clear BadRequest for any name it
doesn’t recognise, so a forgotten implementation surfaces as
an error page rather than a silent no-op.
Sourcefn execute_bulk_action<'a>(
action: &'a str,
_ids: &'a [i64],
_db: &'a Db,
_ctx: &'a BulkActionContext<'a>,
) -> Pin<Box<dyn Future<Output = Result<BulkActionResult>> + Send + 'a>>
fn execute_bulk_action<'a>( action: &'a str, _ids: &'a [i64], _db: &'a Db, _ctx: &'a BulkActionContext<'a>, ) -> Pin<Box<dyn Future<Output = Result<BulkActionResult>> + Send + 'a>>
Run a project-defined bulk action against ids. Called once
per POST /admin/:model/bulk/:name submission with the full
id list — the implementation chooses between a single bulk
SQL update and a per-row loop.
The framework wraps this call with one [audit::record]
emission per submission (using BulkActionContext.actor,
correlation_id, and the BulkActionResult outcome).
Projects don’t need to audit the dispatch envelope themselves;
any business-level audit emissions inside the action body are
still the project’s call.
Two channels for “something went wrong”:
- Action itself failed — return
Err(...). The framework surfaces it as a 4xx/5xx page and still writes an audit row for the attempt. - Some rows failed — return
Ok(BulkActionResult)with a populatedfailedlist. The framework records a partial-success audit row and renders the per-id failure summary on the next request.
The framework’s built-in delete action does not flow
through this method. It runs through the cascade-aware
/bulk_delete route. Override delete semantics on the
underlying crate::Model / handler layer if you need
custom delete behaviour.
The default implementation returns a structured error so a declared-but-unimplemented action surfaces clearly:
use std::future::Future;
use std::pin::Pin;
use rustio_admin::{
BulkAction, BulkActionContext, BulkActionResult, Db, ModelAdmin, Result,
};
impl ModelAdmin for Loan {
fn bulk_actions() -> &'static [BulkAction] {
&[BulkAction {
name: "mark_overdue",
label: "Mark overdue",
destructive: false,
confirm: true,
}]
}
fn execute_bulk_action<'a>(
action: &'a str,
ids: &'a [i64],
_db: &'a Db,
_ctx: &'a BulkActionContext<'a>,
) -> Pin<Box<dyn Future<Output = Result<BulkActionResult>> + Send + 'a>> {
Box::pin(async move {
match action {
"mark_overdue" => Ok(BulkActionResult::ok(ids.len())),
_ => Ok(BulkActionResult::default()),
}
})
}
}Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.