diff options
| author | Tom Christie | 2012-12-15 20:40:41 +0000 | 
|---|---|---|
| committer | Tom Christie | 2012-12-15 20:40:41 +0000 | 
| commit | 35f72cecb199e1790a42fadd6037da43cdd5a05a (patch) | |
| tree | 2cc58cb4f1b03de86eca022fccb59b5174b0b716 | |
| parent | 1d24d1fc5928d32372e700907aa71cf887b16ba9 (diff) | |
| download | django-rest-framework-35f72cecb199e1790a42fadd6037da43cdd5a05a.tar.bz2 | |
Fix model validation exclusions.  Fixes #500.  Fixes #506.
| -rw-r--r-- | docs/topics/release-notes.md | 1 | ||||
| -rw-r--r-- | rest_framework/fields.py | 1 | ||||
| -rw-r--r-- | rest_framework/serializers.py | 25 | ||||
| -rw-r--r-- | rest_framework/tests/models.py | 2 | 
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): | 
