Skip to content

Commit

Permalink
Refs #21286 -- Fixed YAML serialization of TimeField primary key.
Browse files Browse the repository at this point in the history
Handling for PyYAML not being able to serialize `datetime.time`
values is moved from `handle_field` to `_value_from_field` as only
non-primary key, non-relation fields are passed into `handle_field`.
  • Loading branch information
adamzap authored and sarahboyce committed Nov 12, 2024
1 parent c12bc98 commit b9aa323
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 9 deletions.
12 changes: 6 additions & 6 deletions django/core/serializers/pyyaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
"""

import collections
import datetime
import decimal

import yaml

from django.core.serializers.base import DeserializationError
from django.core.serializers.python import Deserializer as PythonDeserializer
from django.core.serializers.python import Serializer as PythonSerializer
from django.db import models

# Use the C (faster) implementation if possible
try:
Expand Down Expand Up @@ -44,17 +44,17 @@ class Serializer(PythonSerializer):

internal_use_only = False

def handle_field(self, obj, field):
def _value_from_field(self, obj, field):
# A nasty special case: base YAML doesn't support serialization of time
# types (as opposed to dates or datetimes, which it does support). Since
# we want to use the "safe" serializer for better interoperability, we
# need to do something with those pesky times. Converting 'em to strings
# isn't perfect, but it's better than a "!!python/time" type which would
# halt deserialization under any other language.
if isinstance(field, models.TimeField) and getattr(obj, field.name) is not None:
self._current[field.name] = str(getattr(obj, field.name))
else:
super().handle_field(obj, field)
value = super()._value_from_field(obj, field)
if isinstance(value, datetime.time):
value = str(value)
return value

def end_serialization(self):
self.options.setdefault("allow_unicode", True)
Expand Down
5 changes: 3 additions & 2 deletions tests/serializers/models/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,9 @@ class SmallPKData(models.Model):
# class TextPKData(models.Model):
# data = models.TextField(primary_key=True)

# class TimePKData(models.Model):
# data = models.TimeField(primary_key=True)

class TimePKData(models.Model):
data = models.TimeField(primary_key=True)


class UUIDData(models.Model):
Expand Down
3 changes: 2 additions & 1 deletion tests/serializers/test_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
Tag,
TextData,
TimeData,
TimePKData,
UniqueAnchor,
UUIDData,
UUIDDefaultData,
Expand Down Expand Up @@ -390,7 +391,7 @@ def inherited_compare(testcase, pk, klass, data):
# It contains line breaks.
# Several of them.
# The end."""),
# (pk_obj, 770, TimePKData, datetime.time(10, 42, 37)),
(pk_obj, 770, TimePKData, datetime.time(10, 42, 37)),
(pk_obj, 791, UUIDData, uuid_obj),
(fk_obj, 792, FKToUUID, uuid_obj),
(pk_obj, 793, UUIDDefaultData, uuid_obj),
Expand Down

0 comments on commit b9aa323

Please sign in to comment.