aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Christie2012-11-09 09:04:45 -0800
committerTom Christie2012-11-09 09:04:45 -0800
commitda1aa5542cff3295d3a53821d4afe02911094181 (patch)
treed40beff70dbc341d0a0b1bc38636a912276d2899
parentb1b284cdbc7732b8825565cf70f8cc56f56971fc (diff)
parente224061189a6a5ea2c063f3820239eed6c3a88fb (diff)
downloaddjango-rest-framework-da1aa5542cff3295d3a53821d4afe02911094181.tar.bz2
Merge pull request #394 from tomchristie/read_only_fields
Read only fields
-rw-r--r--docs/api-guide/serializers.md9
-rw-r--r--docs/index.md7
-rw-r--r--docs/topics/release-notes.md4
-rw-r--r--rest_framework/serializers.py7
-rw-r--r--rest_framework/tests/serializer.py19
5 files changed, 41 insertions, 5 deletions
diff --git a/docs/api-guide/serializers.md b/docs/api-guide/serializers.md
index 0cdae1ce..a9589144 100644
--- a/docs/api-guide/serializers.md
+++ b/docs/api-guide/serializers.md
@@ -248,6 +248,15 @@ The default `ModelSerializer` uses primary keys for relationships, but you can a
The `depth` option should be set to an integer value that indicates the depth of relationships that should be traversed before reverting to a flat representation.
+## Specifying which fields should be read-only
+
+You may wish to specify multiple fields as read-only. Instead of adding each field explicitely with the `read_only=True` attribute, you may use the `read_only_fields` Meta option, like so:
+
+ class AccountSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = Account
+ read_only_fields = ('created', 'modified')
+
## Customising the default fields
You can create customized subclasses of `ModelSerializer` that use a different set of default fields for the representation, by overriding various `get_<field_type>_field` methods.
diff --git a/docs/index.md b/docs/index.md
index 1874ec00..fd834540 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -32,7 +32,7 @@ REST framework requires the following:
The following packages are optional:
-* [Markdown][markdown] (2.1.0+) - Markdown support for the self describing API.
+* [Markdown][markdown] (2.1.0+) - Markdown support for the browseable API.
* [PyYAML][yaml] (3.10+) - YAML content-type support.
* [django-filter][django-filter] (master) - Filtering support.
@@ -41,8 +41,9 @@ The following packages are optional:
Install using `pip`, including any optional packages you want...
pip install djangorestframework
- pip install markdown # Recommended if using the browseable API.
- pip install pyyaml # Required for yaml content-type support.
+ pip install markdown # Markdown support for the browseable API.
+ pip install pyyaml # YAML content-type support.
+ pip install -e git+https://github.com/alex/django-filter.git#egg=django-filter # Filtering support
...or clone the project from github.
diff --git a/docs/topics/release-notes.md b/docs/topics/release-notes.md
index 670332e6..35e8a8b3 100644
--- a/docs/topics/release-notes.md
+++ b/docs/topics/release-notes.md
@@ -4,6 +4,10 @@
>
> &mdash; Eric S. Raymond, [The Cathedral and the Bazaar][cite].
+## Master
+
+* Support for `read_only_fields` on `ModelSerializer` classes.
+
## 2.1.2
**Date**: 9th Nov 2012
diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py
index 95145d58..329b38f2 100644
--- a/rest_framework/serializers.py
+++ b/rest_framework/serializers.py
@@ -321,6 +321,7 @@ class ModelSerializerOptions(SerializerOptions):
def __init__(self, meta):
super(ModelSerializerOptions, self).__init__(meta)
self.model = getattr(meta, 'model', None)
+ self.read_only_fields = getattr(meta, 'read_only_fields', ())
class ModelSerializer(Serializer):
@@ -369,6 +370,12 @@ class ModelSerializer(Serializer):
field.initialize(parent=self, field_name=model_field.name)
ret[model_field.name] = field
+ for field_name in self.opts.read_only_fields:
+ assert field_name in ret, \
+ "read_only_fields on '%s' included invalid item '%s'" % \
+ (self.__class__.__name__, field_name)
+ ret[field_name].read_only = True
+
return ret
def get_pk_field(self, model_field):
diff --git a/rest_framework/tests/serializer.py b/rest_framework/tests/serializer.py
index 8d1de429..059593a9 100644
--- a/rest_framework/tests/serializer.py
+++ b/rest_framework/tests/serializer.py
@@ -51,6 +51,7 @@ class PersonSerializer(serializers.ModelSerializer):
class Meta:
model = Person
fields = ('name', 'age', 'info')
+ read_only_fields = ('age',)
class BasicTests(TestCase):
@@ -107,7 +108,8 @@ class BasicTests(TestCase):
self.assertEquals(serializer.data['sub_comment'], 'And Merry Christmas!')
def test_model_fields_as_expected(self):
- """ Make sure that the fields returned are the same as defined
+ """
+ Make sure that the fields returned are the same as defined
in the Meta data
"""
serializer = PersonSerializer(self.person)
@@ -115,12 +117,25 @@ class BasicTests(TestCase):
set(['name', 'age', 'info']))
def test_field_with_dictionary(self):
- """ Make sure that dictionaries from fields are left intact
+ """
+ Make sure that dictionaries from fields are left intact
"""
serializer = PersonSerializer(self.person)
expected = self.person_data
self.assertEquals(serializer.data['info'], expected)
+ def test_read_only_fields(self):
+ """
+ Attempting to update fields set as read_only should have no effect.
+ """
+
+ serializer = PersonSerializer(self.person, data={'name': 'dwight', 'age': 99})
+ self.assertEquals(serializer.is_valid(), True)
+ instance = serializer.save()
+ self.assertEquals(serializer.errors, {})
+ # Assert age is unchanged (35)
+ self.assertEquals(instance.age, self.person_data['age'])
+
class ValidationTests(TestCase):
def setUp(self):