Skip to content

Commit

Permalink
Merge pull request #23 from uktrade/feature/pagination
Browse files Browse the repository at this point in the history
refactor:pagination logic
  • Loading branch information
hareshkainthdbt authored Oct 16, 2024
2 parents 54658e1 + 7347649 commit 3a2a53e
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 79 deletions.
50 changes: 27 additions & 23 deletions orp/orp_search/public_gateway.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
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
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator

logger = logging.getLogger(__name__)

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

def paginate_results(
def finalise_results(
self, config: SearchDocumentConfig, results, context
) -> Tuple[dict, Paginator]:
) -> dict:
"""
Paginates the given search results based on the provided configuration.
Expand All @@ -66,29 +64,35 @@ def paginate_results(
paginator = Paginator(results, config.limit)
try:
paginated_documents = paginator.page(config.offset)
except InvalidPage:
except PageNotAnInteger:
paginated_documents = paginator.page(1)
except EmptyPage:
paginated_documents = paginator.page(paginator.num_pages)

# Iterate over each document in paginated_documents
if paginated_documents:
for paginated_document in paginated_documents:
if "description" in paginated_document:
paginated_document["description"] = (
paginated_document["description"][:100] + "..."
if len(paginated_document["description"]) > 100
else paginated_document["description"]
)
if "regulatory_topics" in paginated_document:
paginated_document["regulatory_topics"] = str(
paginated_document["regulatory_topics"]
).split("\n")

# Pass the paginated results to the template
context["is_paginated"] = paginator.num_pages > 1
context["results"] = paginated_documents
context["documents"] = paginated_documents
context["paginator"] = paginator
context["page_obj"] = paginated_documents
return context, paginator

def calculate_total_pages(self, config, results_count):
"""
Calculates the total number of pages for pagination.
Args:
total_results (int): The total number of search results.
limit (int): The number of results per page.
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
context["results_count"] = paginator.count
context["results_page_total"] = paginator.num_pages
context["current_page"] = config.offset
return context

def search(self, config: SearchDocumentConfig):
# List of search terms
Expand Down
57 changes: 1 addition & 56 deletions orp/orp_search/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,64 +166,9 @@ def search(request: HttpRequest) -> HttpResponse:

public_gateway = PublicGateway()
search_results = public_gateway.search(config)
context["results_count_total"] = len(search_results)

# search_results contains too much information for the
# landing page (search) so we need to filter it and
# reduce the amount of information to be displayed
# on the landing page.

if 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:
context["results_count"] = len(paginated_search_results)
else:
paginated_search_results = []

context["current_page"] = config.offset
context["results"] = paginated_search_results
context["results_count"] = len(paginated_search_results)
context["results_page_total"] = public_gateway.calculate_total_pages(
config, context["results_count_total"]
)
context = public_gateway.finalise_results(config, search_results, context)

logger.info("search results: %s", context["results"])
logger.info("search results count: %s", context["results_count"])
logger.info(
"search results total count: %s", context["results_count_total"]
)
logger.info("search results page total: %s", context["results_page_total"])
logger.debug("paginated search results: %s", paginated_search_results)
return render(request, template_name="orp.html", context=context)

0 comments on commit 3a2a53e

Please sign in to comment.