From ffae927c93ec9606975b52e8ed390ec65d5166f4 Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Mon, 23 Feb 2026 12:13:33 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=EF=B8=8F(backend)=20remove=20content?= =?UTF-8?q?=20from=20Document=20serializer=20when=20asked?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The frontend can fetch the retrieve endpoint just for having the title. Everytime, the content is added and to get the content, a request is made to the s3 bucket. A query string `without_content` can be used, if the value is `true` then the content is not added (and not also not fetch). --- CHANGELOG.md | 1 + src/backend/core/api/serializers.py | 12 ++++- .../documents/test_api_documents_retrieve.py | 45 +++++++++++++++++++ 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f64608c3..cc5a0730 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to - ✨(frontend) Can print a doc #1832 - ✨(backend) manage reconciliation requests for user accounts #1878 - 👷(CI) add GHCR workflow for forked repo testing #1851 +- ⚡️(backend) remove content from Document serializer when asked #1910 - ✨(backend) allow the duplication of subpages #1893 - ✨(backend) Onboarding docs for new users #1891 - 🩺(trivy) add trivyignore file and add minimatch CVE #1915 diff --git a/src/backend/core/api/serializers.py b/src/backend/core/api/serializers.py index 57ac5bae..a7f3d401 100644 --- a/src/backend/core/api/serializers.py +++ b/src/backend/core/api/serializers.py @@ -225,8 +225,16 @@ class DocumentSerializer(ListDocumentSerializer): fields = super().get_fields() request = self.context.get("request") - if request and request.method == "POST": - fields["id"].read_only = False + if request: + if request.method == "POST": + fields["id"].read_only = False + if ( + serializers.BooleanField().to_internal_value( + request.query_params.get("without_content", False) + ) + is True + ): + del fields["content"] return fields diff --git a/src/backend/core/tests/documents/test_api_documents_retrieve.py b/src/backend/core/tests/documents/test_api_documents_retrieve.py index 59c5e029..f4fae711 100644 --- a/src/backend/core/tests/documents/test_api_documents_retrieve.py +++ b/src/backend/core/tests/documents/test_api_documents_retrieve.py @@ -1057,3 +1057,48 @@ def test_api_documents_retrieve_permanently_deleted_related(role, depth): assert response.status_code == 404 assert response.json() == {"detail": "Not found."} + + +def test_api_documents_retrieve_without_content(): + """ + Test retrieve using without_content query string should remove the content in the response + """ + + user = factories.UserFactory() + + document = factories.DocumentFactory(creator=user, users=[(user, "owner")]) + + client = APIClient() + client.force_login(user) + + with mock.patch("core.models.Document.content") as mock_document_content: + response = client.get( + f"/api/v1.0/documents/{document.id!s}/?without_content=true" + ) + + assert response.status_code == 200 + + payload = response.json() + assert "content" not in payload + mock_document_content.assert_not_called() + + +def test_api_documents_retrieve_without_content_invalid_value(): + """ + Test retrieve using without_content query string but an invalid value + should return a 400 + """ + + user = factories.UserFactory() + + document = factories.DocumentFactory(creator=user, users=[(user, "owner")]) + + client = APIClient() + client.force_login(user) + + response = client.get( + f"/api/v1.0/documents/{document.id!s}/?without_content=invalid-value" + ) + assert response.status_code == 400 + + assert response.json() == ["Must be a valid boolean."]