#filter #diesel #pagination #rocket #json

diesel_filter

柴油过滤是一种快速将过滤和分页添加到您的diesel模型的方法

6个版本 (3个稳定版)

1.0.3 2023年11月6日
1.0.2 2022年9月28日
0.1.2 2022年1月12日
0.1.1 2021年11月10日
0.1.0 2021年8月13日

#322 in 数据库接口

每月38次下载

MIT/Apache

12KB
129

柴油过滤

柴油过滤是一种快速将过滤和分页添加到您的diesel模型的方法。它与 DieselPostgres 一起工作。

包功能

  • rocket 在生成的过滤结构体上推导 FromForm查看此示例
  • actix 在生成的过滤结构体上推导 Deserialize查看此示例
  • pagination 添加了 Paginate 特性 (查看此示例
  • serializepagination 一起添加了可以直接发送到客户端的 PaginatedPayload 特性

用法与示例

Cargo.toml

diesel_filter = { path = "../../diesel_filter/core", features = ["pagination", "serialize", "rocket"] }

使用 DieselFilter 推导您的结构体,并注释要作为过滤器使用的字段。顶级注释 #[diesel(table_name = db_table)] 是必须的。

#[derive(Queryable, DieselFilter)]
#[diesel(table_name = projects)]
pub struct Project {
    pub id: Uuid,
    #[filter(substring, insensitive)]
    pub name: String,
    #[filter(substring)]
    pub owner_email: String,
    #[filter]
    pub owner_id: Uuid,
    pub created_at: NaiveDateTime,
}

#[filter] 注释可以接收要应用的过滤器类型,目前只有 substringinsensitive

将生成一个用于过滤数据的结构体,其名称为 [YourStructName]Filters,例如:ProjectFilters。将生成两个方法(以 Project 为例)

pub fn filter<'a>(filters: &'a ProjectFilters) -> BoxedQuery<'a, Pg>

pub fn filtered(filters: &ProjectFilters, conn: &PgConnection) -> Result<Vec<Project>, Error>

可以与其他diesel方法(如 inner_join)一起使用 filter 方法。

Project::filter(&filters)
    .inner_join(clients::table)
    .select((projects::id, clients::name))
    .load::<ProjectResponse>(conn)

使用Rocket

使用 rocket 功能,可以从前端请求查询参数中获取生成的结构体(点表示法 ?filters.name=xxx

use diesel_filter::PaginatedPayload;

#[get("/?<filters>")]
async fn index(filters: ClientFilters, conn: DbConn) -> Result<Json<PaginatedPayload<Client>>, Error> {
    Ok(Json(
        conn.run(move |conn| Client::filtered(&filters, conn))
            .await?
            .into(),
    ))
}

使用Actix

使用 actix 功能,可以从前端请求查询参数中获取生成的结构体

注意:与 rocket 集成不同,查询参数必须发送为无作用域。例如:?field=xxx&other=1

use diesel_filter::PaginatedPayload;

#[get("/")]
async fn index(filters: web::Query(ClientFilters), conn: DbConn) -> Result<Json<PaginatedPayload<Client>>, Error> {
    Ok(Json(
        conn.run(move |conn| Client::filtered(&filters, conn))
            .await?
            .into(),
    ))
}

分页功能

有了 pagination 功能,您可以访问 paginateper_pageload_and_count 方法。

use diesel_filter::Paginate;

Project::filter(&filters)
    .inner_join(clients::table)
    .select((projects::id, clients::name))
    .paginate(filters.page)
    .per_page(filters.per_page)
    .load_and_count::<ProjectResponse>(conn)

这些方法与您可以在您的结构体上添加的 #[pagination] 注解独立,该注解可以将 pageper_page 添加到生成的过滤器结构体中,并更改 filtered 方法的签名。

#[derive(Queryable, DieselFilter)]
#[diesel(table_name = projects)]
#[pagination]
pub struct Project

要将其转换为 Json,使用功能标志 serialize,您可以使用 PaginatedPayload

pub struct PaginatedPayload<T> {
    data: Vec<T>,
    total: i64,
}
#[get("/?<filters>")]
async fn index(filters: ProjectFilters, conn: DbConn) -> Result<Json<PaginatedPayload<Project>>, Error> {
    Ok(Json(
        conn.run(move |conn| Project::filtered(&filters))
        .await
        .into(),
    ))
}

许可

Diesel 过滤器根据您选择以下之一进行许可

依赖

~1.2–2MB
~47K SLoC