Fix model validation exclusions. Fixes #500. Fixes #506.

This commit is contained in:
Tom Christie 2012-12-15 20:40:41 +00:00
parent 1d24d1fc59
commit 35f72cecb1
4 changed files with 16 additions and 13 deletions

View File

@ -8,6 +8,7 @@
### Master ### Master
* Bugfix: Ensure read-only fields don't have model validation applied.
* Bugfix: Fix hyperlinked fields in paginated results. * Bugfix: Fix hyperlinked fields in paginated results.
### 2.1.9 ### 2.1.9

View File

@ -32,6 +32,7 @@ def is_simple_callable(obj):
class Field(object): class Field(object):
read_only = True
creation_counter = 0 creation_counter = 0
empty = '' empty = ''
type_name = None type_name = None

View File

@ -128,17 +128,6 @@ class BaseSerializer(Field):
""" """
return {} return {}
def get_excluded_fieldnames(self):
"""
Returns the fieldnames that should not be validated.
"""
excluded_fields = list(self.opts.exclude)
if self.opts.fields:
for field in self.fields.keys() + self.get_default_fields().keys():
if field not in list(self.opts.fields) + excluded_fields:
excluded_fields.append(field)
return excluded_fields
def get_fields(self): def get_fields(self):
""" """
Returns the complete set of fields for the object as a dict. Returns the complete set of fields for the object as a dict.
@ -491,6 +480,18 @@ class ModelSerializer(Serializer):
except KeyError: except KeyError:
return ModelField(model_field=model_field, **kwargs) return ModelField(model_field=model_field, **kwargs)
def get_validation_exclusions(self):
"""
Return a list of field names to exclude from model validation.
"""
cls = self.opts.model
opts = get_concrete_model(cls)._meta
exclusions = [field.name for field in opts.fields + opts.many_to_many]
for field_name, field in self.fields.items():
if field_name in exclusions and not field.read_only:
exclusions.remove(field_name)
return exclusions
def restore_object(self, attrs, instance=None): def restore_object(self, attrs, instance=None):
""" """
Restore the model instance. Restore the model instance.
@ -515,7 +516,7 @@ class ModelSerializer(Serializer):
instance = self.opts.model(**attrs) instance = self.opts.model(**attrs)
try: try:
instance.full_clean(exclude=list(self.get_excluded_fieldnames())) instance.full_clean(exclude=self.get_validation_exclusions())
except ValidationError, err: except ValidationError, err:
self._errors = err.message_dict self._errors = err.message_dict
return None return None

View File

@ -61,7 +61,7 @@ class BasicModel(RESTFrameworkModel):
class SlugBasedModel(RESTFrameworkModel): class SlugBasedModel(RESTFrameworkModel):
text = models.CharField(max_length=100) text = models.CharField(max_length=100)
slug = models.SlugField(max_length=32, blank=True) slug = models.SlugField(max_length=32)
class DefaultValueModel(RESTFrameworkModel): class DefaultValueModel(RESTFrameworkModel):