Commit e2240611 by Tom Christie

Support for `read_only_fields` on `ModelSerializer` classes

parent d365621c
...@@ -248,6 +248,15 @@ The default `ModelSerializer` uses primary keys for relationships, but you can a ...@@ -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. 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 ## 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. 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.
......
...@@ -4,6 +4,10 @@ ...@@ -4,6 +4,10 @@
> >
> &mdash; Eric S. Raymond, [The Cathedral and the Bazaar][cite]. > &mdash; Eric S. Raymond, [The Cathedral and the Bazaar][cite].
## Master
* Support for `read_only_fields` on `ModelSerializer` classes.
## 2.1.2 ## 2.1.2
**Date**: 9th Nov 2012 **Date**: 9th Nov 2012
......
...@@ -321,6 +321,7 @@ class ModelSerializerOptions(SerializerOptions): ...@@ -321,6 +321,7 @@ class ModelSerializerOptions(SerializerOptions):
def __init__(self, meta): def __init__(self, meta):
super(ModelSerializerOptions, self).__init__(meta) super(ModelSerializerOptions, self).__init__(meta)
self.model = getattr(meta, 'model', None) self.model = getattr(meta, 'model', None)
self.read_only_fields = getattr(meta, 'read_only_fields', ())
class ModelSerializer(Serializer): class ModelSerializer(Serializer):
...@@ -369,6 +370,12 @@ class ModelSerializer(Serializer): ...@@ -369,6 +370,12 @@ class ModelSerializer(Serializer):
field.initialize(parent=self, field_name=model_field.name) field.initialize(parent=self, field_name=model_field.name)
ret[model_field.name] = field 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 return ret
def get_pk_field(self, model_field): def get_pk_field(self, model_field):
......
...@@ -51,6 +51,7 @@ class PersonSerializer(serializers.ModelSerializer): ...@@ -51,6 +51,7 @@ class PersonSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Person model = Person
fields = ('name', 'age', 'info') fields = ('name', 'age', 'info')
read_only_fields = ('age',)
class BasicTests(TestCase): class BasicTests(TestCase):
...@@ -107,7 +108,8 @@ class BasicTests(TestCase): ...@@ -107,7 +108,8 @@ class BasicTests(TestCase):
self.assertEquals(serializer.data['sub_comment'], 'And Merry Christmas!') self.assertEquals(serializer.data['sub_comment'], 'And Merry Christmas!')
def test_model_fields_as_expected(self): 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 in the Meta data
""" """
serializer = PersonSerializer(self.person) serializer = PersonSerializer(self.person)
...@@ -115,12 +117,25 @@ class BasicTests(TestCase): ...@@ -115,12 +117,25 @@ class BasicTests(TestCase):
set(['name', 'age', 'info'])) set(['name', 'age', 'info']))
def test_field_with_dictionary(self): 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) serializer = PersonSerializer(self.person)
expected = self.person_data expected = self.person_data
self.assertEquals(serializer.data['info'], expected) 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): class ValidationTests(TestCase):
def setUp(self): def setUp(self):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment