|
1 | 1 | import re |
2 | 2 | from collections.abc import MutableMapping |
| 3 | +from datetime import datetime |
| 4 | +from zoneinfo import ZoneInfo |
3 | 5 |
|
4 | 6 | import pytest |
5 | 7 | from django.core.cache import cache |
@@ -488,6 +490,85 @@ class TestSerializer(serializers.Serializer): |
488 | 490 | assert rendered == '' |
489 | 491 |
|
490 | 492 |
|
| 493 | +class TestDateTimeFieldHTMLFormRender(TestCase): |
| 494 | + """ |
| 495 | + Default USE_TZ is True. |
| 496 | + Default TIME_ZONE is 'America/Chicago'. |
| 497 | + """ |
| 498 | + |
| 499 | + def _assert_datetime_rendering(self, appointment, expected, datetimefield_kwargs=None): |
| 500 | + datetimefield_kwargs = datetimefield_kwargs or {} |
| 501 | + |
| 502 | + class TestSerializer(serializers.Serializer): |
| 503 | + appointment = serializers.DateTimeField(**datetimefield_kwargs) |
| 504 | + |
| 505 | + serializer = TestSerializer(data={"appointment": appointment}) |
| 506 | + serializer.is_valid() |
| 507 | + renderer = HTMLFormRenderer() |
| 508 | + field = serializer['appointment'] |
| 509 | + rendered = renderer.render_field(field, {}) |
| 510 | + expected_html = ( |
| 511 | + '<input name="appointment" class="form-control" ' |
| 512 | + f'type="datetime-local" value="{expected}">' |
| 513 | + ) |
| 514 | + |
| 515 | + self.assertInHTML(expected_html, rendered) |
| 516 | + |
| 517 | + def test_datetime_field_rendering_milliseconds(self): |
| 518 | + self._assert_datetime_rendering( |
| 519 | + datetime(2024, 12, 24, 0, 55, 30, 345678), "2024-12-24T00:55:30.345" |
| 520 | + ) |
| 521 | + |
| 522 | + def test_datetime_field_rendering_no_seconds_and_no_milliseconds(self): |
| 523 | + self._assert_datetime_rendering( |
| 524 | + datetime(2024, 12, 24, 0, 55, 0, 0), "2024-12-24T00:55:00.000" |
| 525 | + ) |
| 526 | + |
| 527 | + def test_datetime_field_rendering_with_format_as_none(self): |
| 528 | + self._assert_datetime_rendering( |
| 529 | + datetime(2024, 12, 24, 0, 55, 30, 345678), |
| 530 | + "2024-12-24T00:55:30.345", |
| 531 | + {"format": None} |
| 532 | + ) |
| 533 | + |
| 534 | + def test_datetime_field_rendering_with_format(self): |
| 535 | + self._assert_datetime_rendering( |
| 536 | + datetime(2024, 12, 24, 0, 55, 30, 345678), |
| 537 | + "2024-12-24T00:55:00.000", |
| 538 | + {"format": "%a %d %b %Y, %I:%M%p"} |
| 539 | + ) |
| 540 | + |
| 541 | + # New project templates default to 'UTC'. |
| 542 | + @override_settings(TIME_ZONE='UTC') |
| 543 | + def test_datetime_field_rendering_utc(self): |
| 544 | + self._assert_datetime_rendering( |
| 545 | + datetime(2024, 12, 24, 0, 55, 30, 345678), |
| 546 | + "2024-12-24T00:55:30.345" |
| 547 | + ) |
| 548 | + |
| 549 | + @override_settings(REST_FRAMEWORK={'DATETIME_FORMAT': '%a %d %b %Y, %I:%M%p'}) |
| 550 | + def test_datetime_field_rendering_with_custom_datetime_format(self): |
| 551 | + self._assert_datetime_rendering( |
| 552 | + datetime(2024, 12, 24, 0, 55, 30, 345678), |
| 553 | + "2024-12-24T00:55:00.000" |
| 554 | + ) |
| 555 | + |
| 556 | + @override_settings(REST_FRAMEWORK={'DATETIME_FORMAT': None}) |
| 557 | + def test_datetime_field_rendering_datetime_format_is_none(self): |
| 558 | + self._assert_datetime_rendering( |
| 559 | + datetime(2024, 12, 24, 0, 55, 30, 345678), |
| 560 | + "2024-12-24T00:55:30.345" |
| 561 | + ) |
| 562 | + |
| 563 | + # Enforce it in True because in Django versions under 4.2 was False by default. |
| 564 | + @override_settings(USE_TZ=True) |
| 565 | + def test_datetime_field_rendering_timezone_aware_datetime(self): |
| 566 | + self._assert_datetime_rendering( |
| 567 | + datetime(2024, 12, 24, 0, 55, 30, 345678, tzinfo=ZoneInfo('Asia/Tokyo')), # +09:00 |
| 568 | + "2024-12-23T09:55:30.345" # Rendered in -06:00 |
| 569 | + ) |
| 570 | + |
| 571 | + |
491 | 572 | class TestHTMLFormRenderer(TestCase): |
492 | 573 | def setUp(self): |
493 | 574 | class TestSerializer(serializers.Serializer): |
|
0 commit comments