Make set_value a static method for Serializers

As an alternative to #7671, let the method be overridden if needed. As
the function is only used for serializers, it has a better place in the
Serializer class.
This commit is contained in:
Étienne Beaulé 2021-05-20 12:04:08 -04:00
parent 3875d3284e
commit 17fb350d3f
No known key found for this signature in database
GPG Key ID: 8787C2B2CDA9A57F
2 changed files with 23 additions and 23 deletions

View File

@ -109,27 +109,6 @@ def get_attribute(instance, attrs):
return instance
def set_value(dictionary, keys, value):
"""
Similar to Python's built in `dictionary[key] = value`,
but takes a list of nested keys instead of a single key.
set_value({'a': 1}, [], {'b': 2}) -> {'a': 1, 'b': 2}
set_value({'a': 1}, ['x'], 2) -> {'a': 1, 'x': 2}
set_value({'a': 1}, ['x', 'y'], 2) -> {'a': 1, 'x': {'y': 2}}
"""
if not keys:
dictionary.update(value)
return
for key in keys[:-1]:
if key not in dictionary:
dictionary[key] = {}
dictionary = dictionary[key]
dictionary[keys[-1]] = value
def to_choices_dict(choices):
"""
Convert choices into key/value dicts.

View File

@ -26,7 +26,7 @@ from django.utils.translation import gettext_lazy as _
from rest_framework.compat import postgres_fields
from rest_framework.exceptions import ErrorDetail, ValidationError
from rest_framework.fields import get_error_detail, set_value
from rest_framework.fields import get_error_detail
from rest_framework.settings import api_settings
from rest_framework.utils import html, model_meta, representation
from rest_framework.utils.field_mapping import (
@ -337,6 +337,27 @@ class Serializer(BaseSerializer, metaclass=SerializerMetaclass):
'invalid': _('Invalid data. Expected a dictionary, but got {datatype}.')
}
@staticmethod
def set_value(dictionary, keys, value):
"""
Similar to Python's built in `dictionary[key] = value`,
but takes a list of nested keys instead of a single key.
set_value({'a': 1}, [], {'b': 2}) -> {'a': 1, 'b': 2}
set_value({'a': 1}, ['x'], 2) -> {'a': 1, 'x': 2}
set_value({'a': 1}, ['x', 'y'], 2) -> {'a': 1, 'x': {'y': 2}}
"""
if not keys:
dictionary.update(value)
return
for key in keys[:-1]:
if key not in dictionary:
dictionary[key] = {}
dictionary = dictionary[key]
dictionary[keys[-1]] = value
@cached_property
def fields(self):
"""
@ -483,7 +504,7 @@ class Serializer(BaseSerializer, metaclass=SerializerMetaclass):
except SkipField:
pass
else:
set_value(ret, field.source_attrs, validated_value)
self.set_value(ret, field.source_attrs, validated_value)
if errors:
raise ValidationError(errors)