Skip to content

Commit d894aab

Browse files
committed
Add better approach
1 parent 78e87f8 commit d894aab

File tree

2 files changed

+31
-4
lines changed

2 files changed

+31
-4
lines changed

rest_framework/renderers.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
from django.utils.http import parse_header_parameters
2323
from django.utils.safestring import SafeString
2424

25-
from rest_framework import VERSION, exceptions, serializers, status
25+
from rest_framework import ISO_8601, VERSION, exceptions, serializers, status
2626
from rest_framework.compat import (
2727
INDENT_SEPARATORS, LONG_SEPARATORS, SHORT_SEPARATORS, coreapi, coreschema,
2828
pygments_css, yaml
@@ -343,11 +343,23 @@ def render_field(self, field, parent_style):
343343
field = field.as_form_field()
344344

345345
if style.get('input_type') == 'datetime-local':
346+
# Because DateTimeField.to_representation returns a string,
347+
# need to parse it back to datetime for proper formatting
348+
has_format = hasattr(field._field, "format")
349+
350+
if has_format:
351+
if field._field.format is None:
352+
datetime_field_value = field.value
353+
else:
354+
datetime_field_value = datetime.datetime.strptime(field.value, field._field.format)
355+
else:
356+
if api_settings.DATETIME_FORMAT == ISO_8601:
357+
datetime_field_value = datetime.datetime.fromisoformat(field.value.rstrip('Z'))
358+
346359
# The format of an input type="datetime-local" is "yyyy-MM-ddThh:mm"
347360
# followed by optional ":ss" or ":ss.SSS", so keep only the first three
348361
# digits of milliseconds to avoid browser console error.
349-
datetime_value = field._field.parent.validated_data.get(field.field_name)
350-
field.value = datetime_value.replace(tzinfo=None).isoformat(timespec="milliseconds").rstrip('Z')
362+
field.value = datetime_field_value.replace(tzinfo=None).isoformat(timespec="milliseconds")
351363

352364
if 'template' in style:
353365
template_name = style['template']

tests/test_renderers.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,21 @@ class TestSerializer(serializers.Serializer):
540540
rendered
541541
)
542542

543+
def test_datetime_field_rendering_with_format_as_none(self):
544+
class TestSerializer(serializers.Serializer):
545+
appointment = serializers.DateTimeField(format=None)
546+
547+
appointment = datetime(2024, 12, 24, 0, 55, 30, 345678)
548+
serializer = TestSerializer(data={"appointment": appointment})
549+
serializer.is_valid()
550+
renderer = HTMLFormRenderer()
551+
field = serializer['appointment']
552+
rendered = renderer.render_field(field, {})
553+
self.assertInHTML(
554+
'<input name="appointment" class="form-control" type="datetime-local" value="2024-12-24T00:55:30.345">',
555+
rendered
556+
)
557+
543558
def test_datetime_field_rendering_with_format(self):
544559
class TestSerializer(serializers.Serializer):
545560
appointment = serializers.DateTimeField(format='%a %d %b %Y, %I:%M%p')
@@ -551,7 +566,7 @@ class TestSerializer(serializers.Serializer):
551566
field = serializer['appointment']
552567
rendered = renderer.render_field(field, {})
553568
self.assertInHTML(
554-
'<input name="appointment" class="form-control" type="datetime-local" value="2024-12-24T00:55:30.345">',
569+
'<input name="appointment" class="form-control" type="datetime-local" value="2024-12-24T00:55:00.000">',
555570
rendered
556571
)
557572

0 commit comments

Comments
 (0)