Automatic field binding

This commit is contained in:
Tom Christie 2014-09-25 11:04:18 +01:00
parent 1420c76453
commit b22c9602fa
3 changed files with 26 additions and 8 deletions

View File

@ -10,7 +10,6 @@ from __future__ import unicode_literals
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.http import Http404 from django.http import Http404
from django.utils import six
from django.utils.datastructures import SortedDict from django.utils.datastructures import SortedDict
from rest_framework import exceptions, serializers from rest_framework import exceptions, serializers
from rest_framework.compat import force_text from rest_framework.compat import force_text
@ -100,7 +99,7 @@ class SimpleMetadata(BaseMetadata):
""" """
return SortedDict([ return SortedDict([
(field_name, self.get_field_info(field)) (field_name, self.get_field_info(field))
for field_name, field in six.iteritems(serializer.fields) for field_name, field in serializer.fields.items()
]) ])
def get_field_info(self, field): def get_field_info(self, field):

View File

@ -72,7 +72,6 @@ class BasePaginationSerializer(serializers.Serializer):
child=object_serializer(), child=object_serializer(),
source='object_list' source='object_list'
) )
self.fields[results_field].bind(results_field, self, self)
class PaginationSerializer(BasePaginationSerializer): class PaginationSerializer(BasePaginationSerializer):

View File

@ -149,6 +149,28 @@ class SerializerMetaclass(type):
return super(SerializerMetaclass, cls).__new__(cls, name, bases, attrs) return super(SerializerMetaclass, cls).__new__(cls, name, bases, attrs)
class BindingDict(object):
def __init__(self, serializer):
self.serializer = serializer
self.fields = SortedDict()
def __setitem__(self, key, field):
self.fields[key] = field
field.bind(field_name=key, parent=self.serializer, root=self.serializer)
def __getitem__(self, key):
return self.fields[key]
def __delitem__(self, key):
del self.fields[key]
def items(self):
return self.fields.items()
def values(self):
return self.fields.values()
@six.add_metaclass(SerializerMetaclass) @six.add_metaclass(SerializerMetaclass)
class Serializer(BaseSerializer): class Serializer(BaseSerializer):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -161,11 +183,9 @@ class Serializer(BaseSerializer):
# Every new serializer is created with a clone of the field instances. # Every new serializer is created with a clone of the field instances.
# This allows users to dynamically modify the fields on a serializer # This allows users to dynamically modify the fields on a serializer
# instance without affecting every other serializer class. # instance without affecting every other serializer class.
self.fields = self._get_base_fields() self.fields = BindingDict(self)
for key, value in self._get_base_fields().items():
# Setup all the child fields, to provide them with the current context. self.fields[key] = value
for field_name, field in self.fields.items():
field.bind(field_name, self, self)
def __new__(cls, *args, **kwargs): def __new__(cls, *args, **kwargs):
# We override this method in order to automagically create # We override this method in order to automagically create