From a6687a6b10e59fe769d967dcf8aaf79e20d5cde1 Mon Sep 17 00:00:00 2001 From: Oliver Date: Tue, 25 Aug 2026 11:57:00 +1000 Subject: [PATCH] Bug fix for APISearchView (#12707) The global search endpoint dispatches to viewset-based result types using a bare HttpRequest() with an empty META, so pagination's build_absolute_uri() crashes on the missing SERVER_NAME. --- src/backend/InvenTree/InvenTree/api.py | 8 ++++++++ src/backend/InvenTree/InvenTree/test_api.py | 20 ++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/backend/InvenTree/InvenTree/api.py b/src/backend/InvenTree/InvenTree/api.py index f94e014816..261cc39f3b 100644 --- a/src/backend/InvenTree/InvenTree/api.py +++ b/src/backend/InvenTree/InvenTree/api.py @@ -873,6 +873,14 @@ class APISearchView(GenericAPIView): req.user = request.user req.GET = params + # Copy META from the original request, so that host/scheme + # information is available (e.g. for pagination links). + # Strip content-length/type, as this is a synthetic GET + # request with no body of its own to parse. + req.META = request.META.copy() + req.META.pop('CONTENT_LENGTH', None) + req.META.pop('CONTENT_TYPE', None) + list_method = cls.as_view({'get': 'list'})(req, *args, **kwargs) else: list_method = view.list(request, *args, **kwargs) diff --git a/src/backend/InvenTree/InvenTree/test_api.py b/src/backend/InvenTree/InvenTree/test_api.py index c74632d4bc..8dd1c9f55d 100644 --- a/src/backend/InvenTree/InvenTree/test_api.py +++ b/src/backend/InvenTree/InvenTree/test_api.py @@ -333,6 +333,26 @@ class SearchTests(InvenTreeAPITestCase): response = self.post(reverse('api-search'), d, expected_code=400) self.assertIn('Search term must be provided', str(response.data)) + def test_viewset_pagination(self): + """Test that a paginated 'next' link can be constructed for viewset-backed result types. + + Regression test: the search endpoint dispatches to viewset-based result types + (e.g. PurchaseOrderViewSet) using a synthetic request object. If that request + is missing WSGI environ data (e.g. SERVER_NAME), pagination raises a KeyError + when building the 'next' link. + """ + self.assignRole('purchase_order.view') + + response = self.post( + reverse('api-search'), + {'search': 'PO', 'limit': 2, 'purchaseorder': {}}, + expected_code=200, + ) + + result = response.data['purchaseorder'] + self.assertGreater(result['count'], 2) + self.assertIsNotNone(result['next']) + def test_results(self): """Test individual result types.""" response = self.post(