From 99394c90614cee6ca1b9ed919bf0345e44890dfb Mon Sep 17 00:00:00 2001 From: Mike Fogel Date: Sat, 6 Jul 2024 20:12:15 -0700 Subject: [PATCH] Change base class of TimeZoneSerializerField from DJRF's Field to CharField (#137) * Add tests to clarify allow_null behavior * Subclass CharField instead of Field Add tests to ensure allow_null & allow_blank are working as expected * Add test of required kwarg as well * Add changelog entry * Make the linter happy --- README.md | 1 + tests/test_serializer_field.py | 40 ++++++++++++++++++++++++++++++++ timezone_field/rest_framework.py | 4 ++-- 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8a91722..4cb1e57 100644 --- a/README.md +++ b/README.md @@ -148,6 +148,7 @@ poetry run pytest ([#57](https://github.com/mfogel/django-timezone-field/issues/57)) - Add support for django 5.1 - Drop support for django 3.2, 4.0, 4.1 +- Change subclass of `TimeZoneSerializerField` from DJRF's `Field` to `CharField` ([#137](https://github.com/mfogel/django-timezone-field/issues/137)) #### 6.1.0 (2023-11-25) diff --git a/tests/test_serializer_field.py b/tests/test_serializer_field.py index 460f1df..48e2383 100644 --- a/tests/test_serializer_field.py +++ b/tests/test_serializer_field.py @@ -13,6 +13,17 @@ class _TimeZoneSerializer(serializers.Serializer): yield _TimeZoneSerializer +@pytest.fixture +def TimeZoneSerializerEmpties(use_pytz): + class _TimeZoneSerializer(serializers.Serializer): + # pylint: disable=abstract-method + tz_allow_null = TimeZoneSerializerField(use_pytz=use_pytz, allow_null=True) + tz_allow_blank = TimeZoneSerializerField(use_pytz=use_pytz, allow_blank=True) + tz_not_required = TimeZoneSerializerField(use_pytz=use_pytz, required=False) + + yield _TimeZoneSerializer + + def test_invalid_str(TimeZoneSerializer, invalid_tz): serializer = TimeZoneSerializer(data={"tz": invalid_tz}) assert not serializer.is_valid() @@ -22,6 +33,15 @@ def test_invalid_str(TimeZoneSerializer, invalid_tz): def test_empty_str(TimeZoneSerializer): serializer = TimeZoneSerializer(data={"tz": ""}) assert not serializer.is_valid() + assert serializer.data == {"tz": ""} + assert serializer.validated_data == {} + + +def test_none(TimeZoneSerializer): + serializer = TimeZoneSerializer(data={"tz": None}) + assert not serializer.is_valid() + assert serializer.data == {"tz": None} + assert serializer.validated_data == {} def test_valid(TimeZoneSerializer, pst, pst_tz): @@ -41,3 +61,23 @@ def test_valid_with_timezone_object(TimeZoneSerializer, pst, pst_tz): assert serializer.is_valid() assert serializer.data["tz"] == pst assert serializer.validated_data["tz"] == pst_tz + + +def test_valid_empties(TimeZoneSerializerEmpties): + serializer = TimeZoneSerializerEmpties(data={"tz_allow_null": None, "tz_allow_blank": ""}) + assert serializer.is_valid() + assert serializer.data == {"tz_allow_null": None, "tz_allow_blank": ""} + assert serializer.validated_data == {"tz_allow_null": None, "tz_allow_blank": ""} + + +def test_invalid_empties(TimeZoneSerializerEmpties): + serializer = TimeZoneSerializerEmpties( + data={ + "tz_allow_null": "", + "tz_allow_blank": None, + "tz_not_required": None, + } + ) + assert not serializer.is_valid() + assert serializer.data == {"tz_allow_null": "", "tz_allow_blank": None, "tz_not_required": None} + assert serializer.validated_data == {} diff --git a/timezone_field/rest_framework.py b/timezone_field/rest_framework.py index a75db67..92286d1 100644 --- a/timezone_field/rest_framework.py +++ b/timezone_field/rest_framework.py @@ -1,11 +1,11 @@ from django.utils.encoding import force_str from django.utils.translation import gettext_lazy as _ -from rest_framework.fields import Field +from rest_framework.fields import CharField from timezone_field.backends import TimeZoneNotFoundError, get_tz_backend -class TimeZoneSerializerField(Field): +class TimeZoneSerializerField(CharField): default_error_messages = { "invalid": _("A valid timezone is required."), }