aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Christie2012-12-15 20:40:41 +0000
committerTom Christie2012-12-15 20:40:41 +0000
commit35f72cecb199e1790a42fadd6037da43cdd5a05a (patch)
tree2cc58cb4f1b03de86eca022fccb59b5174b0b716
parent1d24d1fc5928d32372e700907aa71cf887b16ba9 (diff)
downloaddjango-rest-framework-35f72cecb199e1790a42fadd6037da43cdd5a05a.tar.bz2
Fix model validation exclusions. Fixes #500. Fixes #506.
-rw-r--r--docs/topics/release-notes.md1
-rw-r--r--rest_framework/fields.py1
-rw-r--r--rest_framework/serializers.py25
-rw-r--r--rest_framework/tests/models.py2
4 files changed, 16 insertions, 13 deletions
diff --git a/docs/topics/release-notes.md b/docs/topics/release-notes.md
index 4ea393af..6d7dc348 100644
--- a/docs/topics/release-notes.md
+++ b/docs/topics/release-notes.md
@@ -8,6 +8,7 @@
### Master
+* Bugfix: Ensure read-only fields don't have model validation applied.
* Bugfix: Fix hyperlinked fields in paginated results.
### 2.1.9
diff --git a/rest_framework/fields.py b/rest_framework/fields.py
index da588082..d3ef8f77 100644
--- a/rest_framework/fields.py
+++ b/rest_framework/fields.py
@@ -32,6 +32,7 @@ def is_simple_callable(obj):
class Field(object):
+ read_only = True
creation_counter = 0
empty = ''
type_name = None
diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py
index 8026205e..1d93f777 100644
--- a/rest_framework/serializers.py
+++ b/rest_framework/serializers.py
@@ -128,17 +128,6 @@ class BaseSerializer(Field):
"""
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):
"""
Returns the complete set of fields for the object as a dict.
@@ -491,6 +480,18 @@ class ModelSerializer(Serializer):
except KeyError:
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):
"""
Restore the model instance.
@@ -515,7 +516,7 @@ class ModelSerializer(Serializer):
instance = self.opts.model(**attrs)
try:
- instance.full_clean(exclude=list(self.get_excluded_fieldnames()))
+ instance.full_clean(exclude=self.get_validation_exclusions())
except ValidationError, err:
self._errors = err.message_dict
return None
diff --git a/rest_framework/tests/models.py b/rest_framework/tests/models.py
index 428bf130..e2b287d0 100644
--- a/rest_framework/tests/models.py
+++ b/rest_framework/tests/models.py
@@ -61,7 +61,7 @@ class BasicModel(RESTFrameworkModel):
class SlugBasedModel(RESTFrameworkModel):
text = models.CharField(max_length=100)
- slug = models.SlugField(max_length=32, blank=True)
+ slug = models.SlugField(max_length=32)
class DefaultValueModel(RESTFrameworkModel):