]> git.ipfire.org Git - thirdparty/paperless-ngx.git/commitdiff
Fixhancement: trim whitespace for some text searches (#11357)
authorshamoon <4887959+shamoon@users.noreply.github.com>
Fri, 14 Nov 2025 16:09:09 +0000 (08:09 -0800)
committerGitHub <noreply@github.com>
Fri, 14 Nov 2025 16:09:09 +0000 (08:09 -0800)
src-ui/src/app/components/document-list/filter-editor/filter-editor.component.ts
src/documents/filters.py
src/documents/tests/test_api_documents.py
src/documents/views.py

index 9e83797a635d7c697b55ed380e6900a4446edb62..fecbaa17019f84ad76281ef9f2d05676adc06ef1 100644 (file)
@@ -747,7 +747,7 @@ export class FilterEditorComponent
     ) {
       filterRules.push({
         rule_type: FILTER_TITLE_CONTENT,
-        value: this._textFilter,
+        value: this._textFilter.trim(),
       })
     }
     if (this._textFilter && this.textFilterTarget == TEXT_FILTER_TARGET_TITLE) {
@@ -805,7 +805,7 @@ export class FilterEditorComponent
     ) {
       filterRules.push({
         rule_type: FILTER_FULLTEXT_QUERY,
-        value: this._textFilter,
+        value: this._textFilter.trim(),
       })
     }
     if (
index 3a8d4d327fe4d700cfe27b6d2daa8455759c9f9e..54f3c1fa041d35d3aada1cb5cf4c8e4047abc92e 100644 (file)
@@ -160,6 +160,7 @@ class InboxFilter(Filter):
 @extend_schema_field(serializers.CharField)
 class TitleContentFilter(Filter):
     def filter(self, qs, value):
+        value = value.strip() if isinstance(value, str) else value
         if value:
             return qs.filter(Q(title__icontains=value) | Q(content__icontains=value))
         else:
@@ -214,6 +215,7 @@ class CustomFieldFilterSet(FilterSet):
 @extend_schema_field(serializers.CharField)
 class CustomFieldsFilter(Filter):
     def filter(self, qs, value):
+        value = value.strip() if isinstance(value, str) else value
         if value:
             fields_with_matching_selects = CustomField.objects.filter(
                 extra_data__icontains=value,
@@ -244,6 +246,7 @@ class CustomFieldsFilter(Filter):
 
 class MimeTypeFilter(Filter):
     def filter(self, qs, value):
+        value = value.strip() if isinstance(value, str) else value
         if value:
             return qs.filter(mime_type__icontains=value)
         else:
index f7f44c9749e30c796cdfa1e9f810bd4a7d5f338e..87190c23b1a15eb24bf2a37a8b3da727b7592ae5 100644 (file)
@@ -941,6 +941,23 @@ class TestDocumentApi(DirectoriesMixin, DocumentConsumeDelayMixin, APITestCase):
         results = response.data["results"]
         self.assertEqual(len(results), 0)
 
+    def test_documents_title_content_filter_strips_boundary_whitespace(self):
+        doc = Document.objects.create(
+            title="Testwort",
+            content="",
+            checksum="A",
+            mime_type="application/pdf",
+        )
+
+        response = self.client.get(
+            "/api/documents/",
+            {"title_content": " Testwort "},
+        )
+        self.assertEqual(response.status_code, status.HTTP_200_OK)
+        results = response.data["results"]
+        self.assertEqual(len(results), 1)
+        self.assertEqual(results[0]["id"], doc.id)
+
     def test_document_permissions_filters(self):
         """
         GIVEN:
index 822647fdb48951b616dbaa46a0647c0f62124a25..8aee24561eb9e1fea6ddf6f7823c3b9a4c243af7 100644 (file)
@@ -1863,7 +1863,7 @@ class SearchAutoCompleteView(GenericAPIView):
         user = self.request.user if hasattr(self.request, "user") else None
 
         if "term" in request.query_params:
-            term = request.query_params["term"]
+            term = request.query_params["term"].strip()
         else:
             return HttpResponseBadRequest("Term required")