Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore:enhance pagination handling for search results #21

Merged
merged 1 commit into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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