aboutsummaryrefslogtreecommitdiffstats
path: root/docs/api-guide/fields.md
diff options
context:
space:
mode:
authorTom Christie2014-12-02 09:19:59 +0000
committerTom Christie2014-12-02 09:19:59 +0000
commit6ac79b822325784ad145ff0ad064127750c4f7e0 (patch)
treebaa0c3d07c1320c06163a5cd2c400b233458cce0 /docs/api-guide/fields.md
parentf4fc4670ca491eabd5bcdfcef382d8373dd5e380 (diff)
downloaddjango-rest-framework-6ac79b822325784ad145ff0ad064127750c4f7e0.tar.bz2
Document Field.fail(). Closes #2147.
Diffstat (limited to 'docs/api-guide/fields.md')
-rw-r--r--docs/api-guide/fields.md49
1 files changed, 48 insertions, 1 deletions
diff --git a/docs/api-guide/fields.md b/docs/api-guide/fields.md
index 391a52e5..aa5cc84e 100644
--- a/docs/api-guide/fields.md
+++ b/docs/api-guide/fields.md
@@ -453,7 +453,7 @@ If you want to create a custom field, you'll need to subclass `Field` and then o
The `.to_representation()` method is called to convert the initial datatype into a primitive, serializable datatype.
-The `to_internal_value()` method is called to restore a primitive datatype into its internal python representation.
+The `to_internal_value()` method is called to restore a primitive datatype into its internal python representation. This method should raise a `serializer.ValidationError` if the data is invalid.
Note that the `WritableField` class that was present in version 2.x no longer exists. You should subclass `Field` and override `to_internal_value()` if the field supports data input.
@@ -498,6 +498,53 @@ As an example, let's create a field that can be used represent the class name of
"""
return obj.__class__.__name__
+#### Raising validation errors
+
+Our `ColorField` class above currently does not perform any data validation.
+To indicate invalid data, we should raise a `serializers.ValidationError`, like so:
+
+ def to_internal_value(self, data):
+ if not isinstance(data, six.text_type):
+ msg = 'Incorrect type. Expected a string, but got %s'
+ raise ValidationError(msg % type(data).__name__)
+
+ if not re.match(r'^rgb\([0-9]+,[0-9]+,[0-9]+\)$', data):
+ raise ValidationError('Incorrect format. Expected `rgb(#,#,#)`.')
+
+ data = data.strip('rgb(').rstrip(')')
+ red, green, blue = [int(col) for col in data.split(',')]
+
+ if any([col > 255 or col < 0 for col in (red, green, blue)]):
+ raise ValidationError('Value out of range. Must be between 0 and 255.')
+
+ return Color(red, green, blue)
+
+The `.fail()` method is a shortcut for raising `ValidationError` that takes a message string from the `error_messages` dictionary. For example:
+
+ default_error_messages = {
+ 'incorrect_type': 'Incorrect type. Expected a string, but got {input_type}',
+ 'incorrect_format': 'Incorrect format. Expected `rgb(#,#,#)`.',
+ 'out_of_range': 'Value out of range. Must be between 0 and 255.'
+ }
+
+ def to_internal_value(self, data):
+ if not isinstance(data, six.text_type):
+ msg = 'Incorrect type. Expected a string, but got %s'
+ self.fail('incorrect_type', input_type=type(data).__name__)
+
+ if not re.match(r'^rgb\([0-9]+,[0-9]+,[0-9]+\)$', data):
+ self.fail('incorrect_format')
+
+ data = data.strip('rgb(').rstrip(')')
+ red, green, blue = [int(col) for col in data.split(',')]
+
+ if any([col > 255 or col < 0 for col in (red, green, blue)]):
+ self.fail('out_of_range')
+
+ return Color(red, green, blue)
+
+This style keeps you error messages more cleanly separated from your code, and should be preferred.
+
# Third party packages
The following third party packages are also available.