#Customizing Pagination

1 messages · Page 1 of 1 (latest)

tight coral
#

I read through the docs here https://docs.litestar.dev/latest/usage/responses.html#pagination

I want custom pagination behavior where I want the last n results sorted by timestamp

For example this is from the inertia fullstack example

    @get(
        operation_id="ListUsers",
        name="users:list",
        summary="List Users",
        description="Retrieve the users.",
        path="/api/users",
        cache=60,
    )
    async def list_users(
        self,
        users_service: UserService,
        filters: Annotated[list[FilterTypes], Dependency(skip_validation=True)],
    ) -> OffsetPagination[schemas.User]:
        """List users."""
        results, total = await users_service.list_and_count(*filters)
        return users_service.to_schema(data=results, total=total, schema_type=schemas.User, filters=filters)

How do I get the most recent 10 users for instance?

bitter cargoBOT
#
Notes for Customizing Pagination
At your assistance

@tight coral

No Response?

If no response in a reasonable time, ping @Member.

Closing

To close, type !solve or byte solve.

MCVE

Please include an MCVE so that we can reproduce your issue locally.

plucky ledge
#

so, here's the best way I found to do this

#

remove any "default" sorting you've applied to the repository class. we'll use the filters to manage this.

Let me grab the other change to make

unique nebulaBOT
#

app/lib/dependencies.py lines 205 to 207

if order_by.field_name is not None:
    filters.append(order_by)
return filters
plucky ledge
unique nebulaBOT
#

app/lib/dependencies.py line 108

field_name: StringOrNone = Parameter(title="Order by field", query="orderBy", default="updated_at", required=False),
tight coral
#

@plucky ledge I am not sure I understand how the provide works. Would it be possible to change the default sort and order for a single endpoint without changing the defaults for others.

plucky ledge
#

yeah, it should be. are you looking to change the default sort for one table to something like "name" and leave the other at updated_date (or some pattern of this)?

tight coral
#

Yep. But also can you not do it at the controller endpoint level.

In my example

OffsetPagination[schemas.User]

I am presuming would have some default pagination parameters. Only for this specific endpoint can I change the default limit?

plucky ledge
#

yes, i'm thinking the answer is to add a parameter to the provide_order by that defaults to None

#

so you just override the ordery_by dep or something on the controller

#

and it auto-injects

tight coral
#

Maybe I don't understand?

But seems like it already has it right?

def provide_order_by(
    field_name: StringOrNone = Parameter(title="Order by field", query="orderBy", default="updated_at", required=False),
    sort_order: SortOrderOrNone = Parameter(title="Field to search", query="sortOrder", default="desc", required=False),
) -> OrderBy:

My question is how do I override it in a specific endpoint of a controller?

plucky ledge
#

now that I look at the code, i think we need to look at creating some sort of factory to produce the filter dependencies. You can just override it for the controller you want.

this would give the added benefit of allowing you to declare which filters you want to be available on each endpoint more easily.

#

for instance, here's something i was evaluating for services:

def create_async_service_dependency(
    service_class: type[ServiceT],
    statement: Select[tuple[ModelT]] | None = None,
    config: SQLAlchemyAsyncConfig | None = None,
    error_messages: ErrorMessages | None | EmptyType = Empty,
    load: LoadSpec | None = None,
    execution_options: dict[str, Any] | None = None,
) -> Callable[..., AsyncGenerator[ServiceT, None]]:
    """Create a dependency provider for a service."""

    async def provide_service(db_session: AsyncSession | None = None) -> AsyncGenerator[ServiceT, None]:
        async with service_class.new(
            session=db_session,
            statement=statement,
            config=config,
            error_messages=error_messages,
            load=load,
            execution_options=execution_options,
        ) as service:
            yield service

    return provide_service