Skip to content

ModelView's list function failes to apply filters if there is not search action #953

@julian-cellrep

Description

@julian-cellrep

Checklist

  • The bug is reproducible against the latest release or master.
  • There are no similar issues or pull requests to fix it yet.

Describe the bug

When I am using ColumnFilters but no query_search, the pagination failes to count correctly the number of rows

Steps to reproduce the bug

  1. Create a model Admin with a column_filter
  2. Apply the filter through the interface: /admin/molecule/list?fda_max_phase=0.5
  3. The number of rows in the Pagination stays as the total count without the filter

This is modelAdmin

class MoleculeAdmin(ModelView, model=Molecule):
    column_searchable_list = [
        Molecule.name,
    ]
    column_list = [
        Molecule.name,
        Molecule.canonical_smiles,
    ]
    column_filters = [
        FdaMaxPhaseFilter(DrugFeatures.fda_max_phase)
    ]

Expected behavior

When you apply the filter, the total count of the paginator should be the filtered rows count, not the total rows in the table.

Actual behavior

Pagination total count does not change when I change the value of the column_filter

Debugging material

It seems it is an easy fix:

async def list(self, request: Request) -> Pagination:
    page = self.validate_page_number(request.query_params.get("page"), 1)
    page_size = self.validate_page_number(request.query_params.get("pageSize"), 0)
    page_size = min(page_size or self.page_size, max(self.page_size_options))
    search = request.query_params.get("search", None)

    stmt = self.list_query(request)
    for relation in self._list_relations:
        stmt = stmt.options(selectinload(relation))

    for filter in self.get_filters():
        if request.query_params.get(filter.parameter_name):
            stmt = await filter.get_filtered_query(
                stmt, request.query_params.get(filter.parameter_name), self.model
            )

    stmt = self.sort_query(stmt, request)

    # Intead of this
    # if search:
    #     stmt = self.search_query(stmt=stmt, term=search)
    #     count = await self.count(request, select(func.count()).select_from(stmt))
    # else:
    #     count = await self.count(request)

    # it should be like this
    if search:
        stmt = self.search_query(stmt=stmt, term=search)
    # always add stmt to count
    count = await self.count(request, select(func.count()).select_from(stmt))
    

    stmt = stmt.limit(page_size).offset((page - 1) * page_size)
    rows = await self._run_query(stmt)

    pagination = Pagination(
        rows=rows,
        page=page,
        page_size=page_size,
        count=count,
    )

    return pagination

Environment

MAC 0S/ python 3.12/ SQLAdmin 0.21.0

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions