Replace usage of BindingDict and remove it

BindingDict ensures that .bind() is called on each field. However this
is easily ensured without it.

One thing that BindingDict might have helped with is to ensure .bind()
is called even if a field is added after the fact to the dict,
externally. However such use is already broken since _readable_fields
and _writable fields use the fields and are cached. Doing so sounds like
a bad idea, anyway.
This commit is contained in:
Ran Benita 2019-05-09 09:24:54 +03:00
parent db81a1735e
commit 21dc57b46c
2 changed files with 5 additions and 39 deletions

View File

@ -36,8 +36,7 @@ from rest_framework.utils.field_mapping import (
get_relation_kwargs, get_url_kwargs
)
from rest_framework.utils.serializer_helpers import (
BindingDict, BoundField, JSONBoundField, NestedBoundField, ReturnDict,
ReturnList
BoundField, JSONBoundField, NestedBoundField, ReturnDict, ReturnList
)
from rest_framework.validators import (
UniqueForDateValidator, UniqueForMonthValidator, UniqueForYearValidator,
@ -356,9 +355,10 @@ class Serializer(BaseSerializer, metaclass=SerializerMetaclass):
# `fields` is evaluated lazily. We do this to ensure that we don't
# have issues importing modules that use ModelSerializers as fields,
# even if Django's app-loading stage has not yet run.
fields = BindingDict(self)
for key, value in self.get_fields().items():
fields[key] = value
fields = OrderedDict()
for field_name, field in self.get_fields().items():
fields[field_name] = field
field.bind(field_name=field_name, parent=self)
return fields
@cached_property

View File

@ -1,5 +1,4 @@
from collections import OrderedDict
from collections.abc import MutableMapping
from django.utils.encoding import force_text
@ -125,36 +124,3 @@ class NestedBoundField(BoundField):
else:
values[key] = '' if (value is None or value is False) else force_text(value)
return self.__class__(self._field, values, self.errors, self._prefix)
class BindingDict(MutableMapping):
"""
This dict-like object is used to store fields on a serializer.
This ensures that whenever fields are added to the serializer we call
`field.bind()` so that the `field_name` and `parent` attributes
can be set correctly.
"""
def __init__(self, serializer):
self.serializer = serializer
self.fields = OrderedDict()
def __setitem__(self, key, field):
self.fields[key] = field
field.bind(field_name=key, parent=self.serializer)
def __getitem__(self, key):
return self.fields[key]
def __delitem__(self, key):
del self.fields[key]
def __iter__(self):
return iter(self.fields)
def __len__(self):
return len(self.fields)
def __repr__(self):
return dict.__repr__(self.fields)