Fix: correct api created coercion with timezone (#10287)

This commit is contained in:
shamoon 2025-06-28 21:39:14 -07:00 committed by GitHub
parent a9085c65c5
commit 735681d294
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 30 additions and 5 deletions

View File

@ -18,7 +18,11 @@ from django.core.validators import MaxLengthValidator
from django.core.validators import RegexValidator from django.core.validators import RegexValidator
from django.core.validators import integer_validator from django.core.validators import integer_validator
from django.utils.crypto import get_random_string from django.utils.crypto import get_random_string
from django.utils.dateparse import parse_datetime
from django.utils.text import slugify from django.utils.text import slugify
from django.utils.timezone import get_current_timezone
from django.utils.timezone import is_naive
from django.utils.timezone import make_aware
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from drf_spectacular.utils import extend_schema_field from drf_spectacular.utils import extend_schema_field
from drf_spectacular.utils import extend_schema_serializer from drf_spectacular.utils import extend_schema_serializer
@ -972,11 +976,11 @@ class DocumentSerializer(
and ":" in data["created"] and ":" in data["created"]
): ):
# Handle old format of isoformat datetime string # Handle old format of isoformat datetime string
try: parsed = parse_datetime(data["created"])
data["created"] = datetime.fromisoformat(data["created"]).date() if parsed:
except ValueError: # pragma: no cover if is_naive(parsed):
# Just pass, validation will catch it parsed = make_aware(parsed, get_current_timezone())
pass data["created"] = parsed.astimezone().date()
return super().to_internal_value(data) return super().to_internal_value(data)
def validate(self, attrs): def validate(self, attrs):

View File

@ -203,6 +203,27 @@ class TestDocumentApi(DirectoriesMixin, DocumentConsumeDelayMixin, APITestCase):
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data["created"], "2023-01-01") self.assertEqual(response.data["created"], "2023-01-01")
# legacy datetime format
response = self.client.patch(
f"/api/documents/{doc.pk}/",
{"created": "2023-02-01T23:00:00Z"},
format="json",
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
doc.refresh_from_db()
self.assertEqual(doc.created, date(2023, 2, 1))
# naive datetime
response = self.client.patch(
f"/api/documents/{doc.pk}/",
{"created": "2023-06-28T23:00:00"},
format="json",
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
doc.refresh_from_db()
self.assertEqual(doc.created, date(2023, 6, 28))
def test_document_update_legacy_created_format(self): def test_document_update_legacy_created_format(self):
""" """
GIVEN: GIVEN: