diff options
| author | Tom Christie | 2014-10-31 16:38:39 +0000 |
|---|---|---|
| committer | Tom Christie | 2014-10-31 16:38:39 +0000 |
| commit | 207208fedff2457e921ef7d825ea7c3933b5dd6e (patch) | |
| tree | 82ef4afacbc78d7af6f13fb73342794a1102415f /rest_framework | |
| parent | 11075d37709d1ee41f14361cb521ff8d1aa0cc1d (diff) | |
| download | django-rest-framework-207208fedff2457e921ef7d825ea7c3933b5dd6e.tar.bz2 | |
Lazy loading of fields and validators. Closes #1963.
Diffstat (limited to 'rest_framework')
| -rw-r--r-- | rest_framework/fields.py | 21 | ||||
| -rw-r--r-- | rest_framework/serializers.py | 36 | ||||
| -rw-r--r-- | rest_framework/utils/representation.py | 5 |
3 files changed, 39 insertions, 23 deletions
diff --git a/rest_framework/fields.py b/rest_framework/fields.py index d5dccd72..8cc8e81e 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -143,7 +143,7 @@ class Field(object): def __init__(self, read_only=False, write_only=False, required=None, default=empty, initial=empty, source=None, label=None, help_text=None, style=None, - error_messages=None, validators=[], allow_null=False): + error_messages=None, validators=None, allow_null=False): self._creation_counter = Field._creation_counter Field._creation_counter += 1 @@ -166,9 +166,11 @@ class Field(object): self.label = label self.help_text = help_text self.style = {} if style is None else style - self.validators = validators[:] or self.default_validators[:] self.allow_null = allow_null + if validators is not None: + self.validators = validators[:] + # These are set up by `.bind()` when the field is added to a serializer. self.field_name = None self.parent = None @@ -214,6 +216,21 @@ class Field(object): else: self.source_attrs = self.source.split('.') + # .validators is a lazily loaded property, that gets its default + # value from `get_validators`. + @property + def validators(self): + if not hasattr(self, '_validators'): + self._validators = self.get_validators() + return self._validators + + @validators.setter + def validators(self, validators): + self._validators = validators + + def get_validators(self): + return self.default_validators[:] + def get_initial(self): """ Return a value to use when the field is being returned as a primitive diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index c9f70f2d..82e932dd 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -282,21 +282,23 @@ class SerializerMetaclass(type): @six.add_metaclass(SerializerMetaclass) class Serializer(BaseSerializer): - def __init__(self, *args, **kwargs): - super(Serializer, self).__init__(*args, **kwargs) - + @property + def fields(self): + if not hasattr(self, '_fields'): + self._fields = BindingDict(self) + for key, value in self.get_fields().items(): + self._fields[key] = value + return self._fields + + def get_fields(self): # Every new serializer is created with a clone of the field instances. # This allows users to dynamically modify the fields on a serializer # instance without affecting every other serializer class. - self.fields = BindingDict(self) - for key, value in self._get_base_fields().items(): - self.fields[key] = value - - self.validators = getattr(getattr(self, 'Meta', None), 'validators', []) - - def _get_base_fields(self): return copy.deepcopy(self._declared_fields) + def get_validators(self): + return getattr(getattr(self, 'Meta', None), 'validators', []) + def get_initial(self): if self._initial_data is not None: return ReturnDict([ @@ -520,14 +522,6 @@ class ModelSerializer(Serializer): }) _related_class = PrimaryKeyRelatedField - def __init__(self, *args, **kwargs): - super(ModelSerializer, self).__init__(*args, **kwargs) - if 'validators' not in kwargs: - validators = self.get_default_validators() - if validators: - self.validators.extend(validators) - self._kwargs['validators'] = validators - def create(self, validated_attrs): # Check that the user isn't trying to handle a writable nested field. # If we don't do this explicitly they'd likely get a confusing @@ -578,13 +572,13 @@ class ModelSerializer(Serializer): instance.save() return instance - def get_default_validators(self): + def get_validators(self): field_names = set([ field.source for field in self.fields.values() if (field.source != '*') and ('.' not in field.source) ]) - validators = [] + validators = getattr(getattr(self, 'Meta', None), 'validators', []) model_class = self.Meta.model # Note that we make sure to check `unique_together` both on the @@ -627,7 +621,7 @@ class ModelSerializer(Serializer): return validators - def _get_base_fields(self): + def get_fields(self): declared_fields = copy.deepcopy(self._declared_fields) ret = SortedDict() diff --git a/rest_framework/utils/representation.py b/rest_framework/utils/representation.py index 180b51f8..2a7c4675 100644 --- a/rest_framework/utils/representation.py +++ b/rest_framework/utils/representation.py @@ -82,6 +82,11 @@ def serializer_repr(serializer, indent, force_many=None): ret += field_repr(field.child_relation, force_many=field.child_relation) else: ret += field_repr(field) + + if serializer.validators: + ret += '\n' + indent_str + 'class Meta:' + ret += '\n' + indent_str + ' validators = ' + smart_repr(serializer.validators) + return ret |
