Sorting¶
fastapi-filters provides built-in sorting support that integrates with the same database backends
as filtering.
Basic Usage¶
Use create_sorting to define sortable fields:
from fastapi import Depends, FastAPI
from fastapi_filters import SortingValues, create_sorting
app = FastAPI()
@app.get("/users")
async def get_users(
sorting: SortingValues = Depends(create_sorting("age", "created_at")),
):
return {"sorting": sorting}
Clients specify sort order using + (ascending) and - (descending) prefixes:
GET /users?sort=+age,-created_at
Default Sort¶
Set a default sort order that applies when no sort parameter is provided:
sorting = create_sorting(
"age", "created_at",
default="+age",
)
# Multiple defaults
sorting = create_sorting(
"age", "created_at",
default=["+age", "-created_at"],
)
From Pydantic Model¶
Auto-generate sortable fields from a Pydantic model:
from pydantic import BaseModel
from fastapi_filters import create_sorting_from_model
class UserOut(BaseModel):
name: str
age: int
created_at: datetime
sorting = create_sorting_from_model(
UserOut,
default="+age",
exclude={"name"}, # exclude specific fields
)
Complex fields (nested models, lists) are automatically excluded.
NULL Positioning¶
Control where NULL values appear in sorted results:
sorting = create_sorting(
"age",
("created_at", "bigger"), # NULLs sort as "bigger" (last in ASC, first in DESC)
("deleted_at", "smaller"), # NULLs sort as "smaller" (first in ASC, last in DESC)
)
Combined with Filters¶
Sorting works alongside FilterSet in your endpoints:
from fastapi_filters import FilterField, FilterSet, SortingValues, create_sorting
class UserFilters(FilterSet):
name: FilterField[str]
age: FilterField[int]
is_active: FilterField[bool]
@app.get("/users")
async def get_users(
filters: UserFilters = Depends(),
sorting: SortingValues = Depends(create_sorting("age", "created_at")),
):
...
And applied together with database integrations:
from sqlalchemy import select
from fastapi_filters.ext.sqlalchemy import apply_filters_and_sorting
@app.get("/users")
async def get_users(
filters: UserFilters = Depends(),
sorting: SortingValues = Depends(create_sorting("age", "created_at")),
):
stmt = apply_filters_and_sorting(select(User), filters, sorting)
...
Custom Query Parameter Alias¶
By default, the sorting parameter is named sort. You can change it:
sorting = create_sorting(
"age", "created_at",
alias="order_by",
)
Now clients use ?order_by=+age,-created_at.
SortingValues Structure¶
SortingValues is a list of tuples: list[tuple[str, SortingDirection, SortingNulls]]
str-- field nameSortingDirection--"asc"or"desc"SortingNulls--"bigger","smaller", orNone
# GET /users?sort=+age,-created_at
# Produces:
[
("age", "asc", None),
("created_at", "desc", None),
]