diff --git a/spp_api/__manifest__.py b/spp_api/__manifest__.py index 73a1911c..303ec0ad 100644 --- a/spp_api/__manifest__.py +++ b/spp_api/__manifest__.py @@ -7,7 +7,7 @@ "images": [ "images/icon.png", ], - "version": "17.0.1.3.1", + "version": "17.0.1.4.1", "application": False, "author": "OpenSPP.org", "development_status": "Production/Stable", diff --git a/spp_api/controllers/api.py b/spp_api/controllers/api.py index ca1a44d6..f877aa17 100644 --- a/spp_api/controllers/api.py +++ b/spp_api/controllers/api.py @@ -207,21 +207,46 @@ def read_multi__GET(self, namespace, version, model, **kw): path = kw.get("path") del kw["path"] + # For backward compatibility + # Will not use pagination + backward_compat = False + if "start_from" in kw: + backward_compat = True + + try: + page = int(kw.get("page", 1)) + except (ValueError, TypeError): + page = 1 + page = max(1, page) + kw["page"] = page + kw = path.search_treatment_kwargs(kw) + limit = kw.get("limit") + records = self.get_records(path.model, kw) records_data = records.search_read(**kw) records_all = records.search_count(kw.get("domain")) records_data = path._get_response_treatment(records_data) + response_data = { "results": records_data, - "count": records_all, - "offset": kw.get("offset", 0), - "limit": kw.get("limit", 0), "version": version, "timestamp": datetime_format(datetime.datetime.now()), "reply_id": self.get_reply_id(), } + if backward_compat: + response_data["count"] = records_all + response_data["offset"] = kw.get("offset", 0) + response_data["limit"] = limit + else: + response_data["pagination"] = { + "page": page, + "limit": limit, + "total_records": records_all, + "total_pages": max(1, (records_all + limit - 1) // limit if limit > 0 else 1), + } + return successful_response(200, response_data) # ReadOne (optional: include_fields, exclude_fields) diff --git a/spp_api/models/spp_api_path.py b/spp_api/models/spp_api_path.py index 26bc8190..711c8f08 100644 --- a/spp_api/models/spp_api_path.py +++ b/spp_api/models/spp_api_path.py @@ -89,7 +89,7 @@ class SPPAPIPath(models.Model): # Read filter_domain = fields.Char(default="[]") field_ids = fields.Many2many("ir.model.fields", domain="[('model_id', '=', model_id)]", string="Fields") - limit = fields.Integer(string="Limit of results", default=500) + limit = fields.Integer(string="Limit of results", default=500, help="Limit of results per page") # Create / Update warning_required = fields.Boolean(compute="_compute_warning_required", compute_sudo=True) api_field_ids = fields.One2many("spp_api.field", "path_id", string="API Fields", copy=True) @@ -663,15 +663,39 @@ def search_treatment_kwargs(self, kwargs): """ self.ensure_one() - # Limit - limit = kwargs.get("limit", 0) - max_limit = self.limit if self.limit else MAX_LIMIT - kwargs["limit"] = limit if (limit and limit <= max_limit) else max_limit - - # Offset - kwargs["offset"] = kwargs.get("start_from", 0) + backward_compat = False if "start_from" in kwargs: - del kwargs["start_from"] + backward_compat = True + + if backward_compat: + limit = kwargs.get("limit", 0) + max_limit = self.limit if self.limit else MAX_LIMIT + kwargs["limit"] = limit if (limit and limit <= max_limit) else max_limit + kwargs["offset"] = kwargs.get("start_from", 0) + if "start_from" in kwargs: + del kwargs["start_from"] + else: + # Page + page = int(kwargs.get("page", 1)) + + # Get defined limit first in spp_api.path + # if limit is defined in kwargs (query parameter), use it; else use self.limit or MAX_LIMIT + max_limit = self.limit if self.limit else MAX_LIMIT + limit = kwargs.get("limit", max_limit) + + # Validate limit + try: + limit = int(limit) + if limit <= 0 or limit > max_limit: + limit = max_limit + except (ValueError, TypeError): + limit = max_limit + + kwargs["limit"] = limit + + # Offset + offset = (page - 1) * limit + kwargs["offset"] = offset # Domain kwargs["domain"] = self.get_domain(kwargs)