aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Christie2013-06-02 20:12:49 +0100
committerTom Christie2013-06-02 20:12:49 +0100
commitb15a6ccef2e13ab3310dbe856a945bba56e21c63 (patch)
treeeedeffadf8f6fa48d339940e8bba64e33b33db7d
parent01e80ff9f77c075a01fc84c93f511a8b16ab3045 (diff)
downloaddjango-rest-framework-b15a6ccef2e13ab3310dbe856a945bba56e21c63.tar.bz2
Serializer field 'default' argument may be a callable
-rw-r--r--docs/api-guide/fields.md4
-rw-r--r--docs/topics/release-notes.md1
-rw-r--r--rest_framework/fields.py8
-rw-r--r--rest_framework/tests/test_fields.py14
4 files changed, 22 insertions, 5 deletions
diff --git a/docs/api-guide/fields.md b/docs/api-guide/fields.md
index 9820cb40..c7db32ed 100644
--- a/docs/api-guide/fields.md
+++ b/docs/api-guide/fields.md
@@ -41,7 +41,9 @@ Defaults to `True`.
### `default`
-If set, this gives the default value that will be used for the field if none is supplied. If not set the default behavior is to not populate the attribute at all.
+If set, this gives the default value that will be used for the field if none is supplied. If not set the default behavior is to not populate the attribute at all.
+
+May be set to a function or other callable, in which case the value will be evaluated each time it is used.
### `validators`
diff --git a/docs/topics/release-notes.md b/docs/topics/release-notes.md
index 77cd4f9e..6eb18160 100644
--- a/docs/topics/release-notes.md
+++ b/docs/topics/release-notes.md
@@ -43,6 +43,7 @@ You can determine your currently installed version using `pip freeze`:
### Master
* Added `get_url` hook to `HyperlinkedIdentityField`.
+* Serializer field `default` argument may be a callable.
* Bugfix: The `lookup_field` option on `HyperlinkedIdentityField` should apply by default to the url field on the serializer.
* Bugfix: `HyperlinkedIdentityField` should continue to support `pk_url_kwarg`, `slug_url_kwarg`, `slug_field`, in a pending deprecation state.
* Bugfix: Ensure we always return 404 instead of 500 if a lookup field cannot be converted to the correct lookup type. (Eg non-numeric `AutoInteger` pk lookup)
diff --git a/rest_framework/fields.py b/rest_framework/fields.py
index 30bbafc4..535aa2ac 100644
--- a/rest_framework/fields.py
+++ b/rest_framework/fields.py
@@ -250,9 +250,6 @@ class WritableField(Field):
self.validators = self.default_validators + validators
self.default = default if default is not None else self.default
- if is_simple_callable(self.default):
- self.default = self.default()
-
# Widgets are ony used for HTML forms.
widget = widget or self.widget
if isinstance(widget, type):
@@ -298,7 +295,10 @@ class WritableField(Field):
except KeyError:
if self.default is not None and not self.partial:
# Note: partial updates shouldn't set defaults
- native = self.default
+ if is_simple_callable(self.default):
+ native = self.default()
+ else:
+ native = self.default
else:
if self.required:
raise ValidationError(self.error_messages['required'])
diff --git a/rest_framework/tests/test_fields.py b/rest_framework/tests/test_fields.py
index 3f956051..de371001 100644
--- a/rest_framework/tests/test_fields.py
+++ b/rest_framework/tests/test_fields.py
@@ -852,3 +852,17 @@ class FieldMetadata(TestCase):
def test_label(self):
for field in (self.required_field, self.optional_field):
self.assertEqual(field.metadata()['label'], field.label)
+
+
+class FieldCallableDefault(TestCase):
+ def setUp(self):
+ self.simple_callable = lambda: 'foo bar'
+
+ def test_default_can_be_simple_callable(self):
+ """
+ Ensure that the 'default' argument can also be a simple callable.
+ """
+ field = serializers.WritableField(default=self.simple_callable)
+ into = {}
+ field.field_from_native({}, {}, 'field', into)
+ self.assertEquals(into, {'field': 'foo bar'})