diff --git a/docs/api.md b/docs/api.md index 44c9a4bc4..ac2789f8b 100644 --- a/docs/api.md +++ b/docs/api.md @@ -418,3 +418,9 @@ Initial API version. - The user field of document notes now returns a simplified user object rather than just the user ID. + +#### Version 9 + +- The document `created` field is now a date, not a datetime. The + `created_date` field is considered deprecated and will be removed in a + future version. diff --git a/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html b/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html index 305584a64..53fa86dd3 100644 --- a/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html +++ b/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html @@ -43,7 +43,7 @@ {{doc.added | customDate}} } @case (DisplayField.CREATED) { - {{doc.created_date | customDate}} + {{doc.created | customDate}} } @case (DisplayField.TITLE) { {{doc.title | documentTitle}} diff --git a/src-ui/src/app/components/document-detail/document-detail.component.html b/src-ui/src/app/components/document-detail/document-detail.component.html index 19d6faabb..067246335 100644 --- a/src-ui/src/app/components/document-detail/document-detail.component.html +++ b/src-ui/src/app/components/document-detail/document-detail.component.html @@ -129,8 +129,8 @@
- +
- Created: {{ document.created_date | customDate }} + Created: {{ document.created | customDate }} Added: {{ document.added | customDate }} Modified: {{ document.modified | customDate }}
@if (displayFields.includes(DisplayField.CREATED)) {
- {{document.created_date | customDate:'mediumDate'}} + {{document.created | customDate:'mediumDate'}}
} @if (displayFields.includes(DisplayField.ADDED)) { diff --git a/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.html b/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.html index a166acd94..662bb9bab 100644 --- a/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.html +++ b/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.html @@ -73,14 +73,14 @@
- Created: {{ document.created_date | customDate }} + Created: {{ document.created | customDate }} Added: {{ document.added | customDate }} Modified: {{ document.modified | customDate }}
- {{document.created_date | customDate:'mediumDate'}} + {{document.created | customDate:'mediumDate'}}
} diff --git a/src-ui/src/app/components/document-list/document-list.component.html b/src-ui/src/app/components/document-list/document-list.component.html index e50805098..c58d1ede1 100644 --- a/src-ui/src/app/components/document-list/document-list.component.html +++ b/src-ui/src/app/components/document-list/document-list.component.html @@ -348,7 +348,7 @@ } @if (activeDisplayFields.includes(DisplayField.CREATED)) { - {{d.created_date | customDate}} + {{d.created | customDate}} } @if (activeDisplayFields.includes(DisplayField.ADDED)) { diff --git a/src-ui/src/app/data/document.ts b/src-ui/src/app/data/document.ts index e5f00148e..5c23a8600 100644 --- a/src-ui/src/app/data/document.ts +++ b/src-ui/src/app/data/document.ts @@ -130,9 +130,6 @@ export interface Document extends ObjectWithPermissions { // UTC created?: Date - // localized date - created_date?: Date - modified?: Date added?: Date diff --git a/src-ui/src/app/services/rest/document.service.ts b/src-ui/src/app/services/rest/document.service.ts index 9cdb86280..1f67a358b 100644 --- a/src-ui/src/app/services/rest/document.service.ts +++ b/src-ui/src/app/services/rest/document.service.ts @@ -190,8 +190,6 @@ export class DocumentService extends AbstractPaperlessService { } patch(o: Document): Observable { - // we want to only set created_date - delete o.created o.remove_inbox_tags = !!this.settingsService.get( SETTINGS_KEYS.DOCUMENT_EDITING_REMOVE_INBOX_TAGS ) diff --git a/src-ui/src/environments/environment.prod.ts b/src-ui/src/environments/environment.prod.ts index 2bc42f4e9..a05991d9e 100644 --- a/src-ui/src/environments/environment.prod.ts +++ b/src-ui/src/environments/environment.prod.ts @@ -3,7 +3,7 @@ const base_url = new URL(document.baseURI) export const environment = { production: true, apiBaseUrl: document.baseURI + 'api/', - apiVersion: '8', // match src/paperless/settings.py + apiVersion: '9', // match src/paperless/settings.py appTitle: 'Paperless-ngx', version: '2.15.3', webSocketHost: window.location.host, diff --git a/src/documents/serialisers.py b/src/documents/serialisers.py index 062775544..9782932bc 100644 --- a/src/documents/serialisers.py +++ b/src/documents/serialisers.py @@ -21,6 +21,7 @@ from django.utils.crypto import get_random_string from django.utils.text import slugify from django.utils.translation import gettext as _ from drf_spectacular.utils import extend_schema_field +from drf_spectacular.utils import extend_schema_serializer from drf_writable_nested.serializers import NestedUpdateMixin from guardian.core import ObjectPermissionChecker from guardian.shortcuts import get_users_with_perms @@ -891,6 +892,9 @@ class NotesSerializer(serializers.ModelSerializer): return ret +@extend_schema_serializer( + deprecate_fields=["created_date"], +) class DocumentSerializer( OwnedObjectSerializer, NestedUpdateMixin, @@ -943,6 +947,22 @@ class DocumentSerializer( doc = super().to_representation(instance) if self.truncate_content and "content" in self.fields: doc["content"] = doc.get("content")[0:550] + + request = self.context.get("request") + api_version = int( + request.version if request else settings.REST_FRAMEWORK["DEFAULT_VERSION"], + ) + + if api_version < 9: + # provide created as a datetime for backwards compatibility + from django.utils import timezone + + doc["created"] = timezone.make_aware( + datetime.combine( + instance.created, + datetime.min.time(), + ), + ).isoformat() return doc def validate(self, attrs): @@ -968,6 +988,9 @@ class DocumentSerializer( instance.created = validated_data.get("created_date") instance.save() if "created_date" in validated_data: + logger.warning( + "created_date is deprecated, use created instead", + ) validated_data.pop("created_date") if instance.custom_fields.count() > 0 and "custom_fields" in validated_data: incoming_custom_fields = [ diff --git a/src/documents/tests/test_api_documents.py b/src/documents/tests/test_api_documents.py index c63ffdb57..bb77f5818 100644 --- a/src/documents/tests/test_api_documents.py +++ b/src/documents/tests/test_api_documents.py @@ -171,6 +171,38 @@ class TestDocumentApi(DirectoriesMixin, DocumentConsumeDelayMixin, APITestCase): results = response.data["results"] self.assertEqual(len(results[0]), 0) + def test_document_legacy_created_format(self): + """ + GIVEN: + - Existing document + WHEN: + - Document is requested with api version ≥ 9 + - Document is requested with api version < 9 + THEN: + - Document created field is returned as date + - Document created field is returned as datetime + """ + doc = Document.objects.create( + title="none", + checksum="123", + mime_type="application/pdf", + created=date(2023, 1, 1), + ) + + response = self.client.get( + f"/api/documents/{doc.pk}/", + headers={"Accept": "application/json; version=8"}, + ) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertRegex(response.data["created"], r"^2023-01-01T00:00:00.*$") + + response = self.client.get( + f"/api/documents/{doc.pk}/", + headers={"Accept": "application/json; version=9"}, + ) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.data["created"], "2023-01-01") + def test_document_update_with_created_date(self): """ GIVEN: diff --git a/src/paperless/settings.py b/src/paperless/settings.py index 3e6e76f11..1eaf93920 100644 --- a/src/paperless/settings.py +++ b/src/paperless/settings.py @@ -342,10 +342,10 @@ REST_FRAMEWORK = { "rest_framework.authentication.SessionAuthentication", ], "DEFAULT_VERSIONING_CLASS": "rest_framework.versioning.AcceptHeaderVersioning", - "DEFAULT_VERSION": "8", # match src-ui/src/environments/environment.prod.ts + "DEFAULT_VERSION": "9", # match src-ui/src/environments/environment.prod.ts # Make sure these are ordered and that the most recent version appears # last. See api.md#api-versioning when adding new versions. - "ALLOWED_VERSIONS": ["1", "2", "3", "4", "5", "6", "7", "8"], + "ALLOWED_VERSIONS": ["1", "2", "3", "4", "5", "6", "7", "8", "9"], # DRF Spectacular default schema "DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema", }