Skip to content

Commit

Permalink
chore:enhance pagination handling for search results
Browse files Browse the repository at this point in the history
Refactor pagination to use Django Paginator for improved reliability. The context is now updated with pagination details and results are consistently aggregated across all pages for accurate representation.
  • Loading branch information
hareshkainthdbt committed Oct 16, 2024
1 parent f88a6a6 commit 95c7ce1
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 32 deletions.
43 changes: 34 additions & 9 deletions orp/orp_search/public_gateway.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import logging

from typing import Tuple

import pandas as pd
import requests # type: ignore

from jinja2 import Template
from orp_search.config import SearchDocumentConfig
from orp_search.dummy_data import get_construction_data_as_dataframe

from django.core.paginator import InvalidPage, Paginator

logger = logging.getLogger(__name__)


Expand Down Expand Up @@ -35,20 +39,40 @@ def _build_like_conditions(self, field, terms):
"""
return " OR ".join([f"{field} LIKE '%{term}%'" for term in terms])

def paginate_results(self, config: SearchDocumentConfig, results):
def paginate_results(
self, config: SearchDocumentConfig, results, context
) -> Tuple[dict, Paginator]:
"""
Paginates the search results.
Paginates the given search results based on the provided configuration.
Args:
results (list): The search results to paginate.
Arguments:
config (SearchDocumentConfig): Configuration parameters for search,
including pagination limits.
results: A collection of search results to be paginated.
context: A dictionary containing context data which will be updated
with pagination details.
Returns:
list: The paginated search results.
count: Total number of pages from results
A tuple containing:
- Updated context dictionary with pagination information.
- Paginator instance used for paginating the results.
The context dictionary is updated with the following keys:
is_paginated: A boolean indicating if the results span multiple pages.
reports: The paginated results for the current page.
paginator: The Paginator instance.
page_obj: The current page of results.
"""
start = (config.offset - 1) * config.limit
end = start + config.limit
return results[start:end]
paginator = Paginator(results, config.limit)
try:
paginated_reports = paginator.page(config.offset)
except InvalidPage:
paginated_reports = paginator.page(1)
context["is_paginated"] = paginator.num_pages > 1
context["reports"] = paginated_reports
context["paginator"] = paginator
context["page_obj"] = paginated_reports
return context, paginator

def calculate_total_pages(self, config, results_count):
"""
Expand All @@ -61,6 +85,7 @@ def calculate_total_pages(self, config, results_count):
Returns:
int: The total number of pages.
"""

if config.limit <= 0:
raise ValueError("limit must be greater than 0")
return (results_count + config.limit - 1) // config.limit
Expand Down
54 changes: 31 additions & 23 deletions orp/orp_search/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,32 +174,40 @@ def search(request: HttpRequest) -> HttpResponse:
# on the landing page.

if search_results:
paginated_search_results = public_gateway.paginate_results(
config, search_results
)
logger.info(
"paginated search results after paginate: %s",
paginated_search_results,
context, paginator = public_gateway.paginate_results(
config, search_results, context
)

# Initialize a list to hold all results from all pages
paginated_search_results = []

# Iterate over each page
for page_num in paginator.page_range:
# Get the page
page = paginator.page(page_num)
# Add the objects of the current page to the aggregate list

for result in page.object_list:
paginated_search_results.append(
{
"id": result["id"],
"title": result["title"],
"publisher": result["publisher"],
"description": (
result["description"][:100] + "..."
if len(result["description"]) > 100
else result["description"]
),
"date_issued": result["date_issued"],
"date_modified": result["date_modified"],
"document_type": result["type"],
"regulatory_topics": result["regulatory_topics"].split(
"\n"
),
}
)

# We can use the following code to filter the search_results list:
paginated_search_results = [
{
"id": result["id"],
"title": result["title"],
"publisher": result["publisher"],
"description": (
result["description"][:100] + "..."
if len(result["description"]) > 100
else result["description"]
),
"date_issued": result["date_issued"],
"date_modified": result["date_modified"],
"document_type": result["type"],
"regulatory_topics": result["regulatory_topics"].split("\n"),
}
for result in paginated_search_results
]
context["results_count"] = len(paginated_search_results)
else:
paginated_search_results = []
Expand Down

0 comments on commit 95c7ce1

Please sign in to comment.