Skip to content

Commit

Permalink
chore: reusable pagination code
Browse files Browse the repository at this point in the history
  • Loading branch information
Yuefii committed Aug 25, 2024
1 parent 40ff40a commit 343fb04
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 25 deletions.
34 changes: 9 additions & 25 deletions app/routes.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from flask import Blueprint, jsonify, request
from app.models import Districts, Provinces, Regencies, Villages
from app.utils.pagination_query import Pagination

province_bp = Blueprint("provinces", __name__)
regency_bp = Blueprint("regencies", __name__)
Expand All @@ -12,38 +13,21 @@ def get_provinces():
show_all = request.args.get("show_all", "false").lower() == "true"
page = request.args.get("page", 1, type=int)
per_page = request.args.get("per_page", 10, type=int)

if per_page <= 0:
return jsonify({"error": "invalid per_page value"}), 400

if show_all:
provinces = Provinces.query.all()
response = [
{"code": province.code, "name": province.name} for province in provinces
]
else:
total_provinces = Provinces.query.count()
total_pages = (total_provinces + per_page - 1) // per_page

if page > total_pages:
return jsonify({"error": "Page number exceeds total pages"}), 400

provinces_query = Provinces.query.paginate(
page=page, per_page=per_page, error_out=False
)

response = {
"pagination": {
"total_items": provinces_query.total,
"total_pages": provinces_query.pages,
"current_page": provinces_query.page,
"per_page": provinces_query.per_page,
},
"data": [
{"code": province.code, "name": province.name}
for province in provinces_query.items
],
{"code": province.code, "name": province.name} for province in provinces
]
}
else:
try:
pagination = Pagination(Provinces.query, page, per_page)
response = pagination.get_paginated_data()
except ValueError as e:
return jsonify({"error": str(e)}), 400
return jsonify(response)


Expand Down
Empty file added app/utils/__init__.py
Empty file.
46 changes: 46 additions & 0 deletions app/utils/pagination_query.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
class Pagination:
def __init__(self, query, page=1, per_page=10):
self.query = query
self.page = self._validate_page(page)
self.per_page = self._validate_per_page(per_page)

def _validate_page(self, page):
try:
page = int(page)
except ValueError:
raise ValueError("Page must be an integer")
if page < 1:
raise ValueError("Page number must be greater than zero")
return page

def _validate_per_page(self, per_page):
try:
per_page = int(per_page)
except ValueError:
raise ValueError("per_page must be an integer")
if per_page <= 0:
raise ValueError("per_page must be greater than zero")
return per_page

def get_paginated_data(self):
total_items = self.query.count()
total_pages = (total_items + self.per_page - 1) // self.per_page

if self.page > total_pages:
raise ValueError("Page number exceeds total pages")

paginated_query = self.query.paginate(
page=self.page, per_page=self.per_page, error_out=False
)

return {
"pagination": {
"total_items": paginated_query.total,
"total_pages": paginated_query.pages,
"current_page": paginated_query.page,
"per_page": paginated_query.per_page,
},
"data": [
{"code": item.code, "name": item.name} for item in paginated_query.items
],
}

0 comments on commit 343fb04

Please sign in to comment.