diff options
| author | Tom Christie | 2014-11-28 09:57:02 +0000 |
|---|---|---|
| committer | Tom Christie | 2014-11-28 09:57:02 +0000 |
| commit | d4b8e356b952137760bf33750b17895526d6151e (patch) | |
| tree | cb4428b2967582dd8ca50cb1bcd1f7bb95b1fe5f /docs/topics/3.0-announcement.md | |
| parent | d2d7e1dfde2a62ee8f6d904368dbd6581de278c9 (diff) | |
| parent | 34ca8cd2a5c030d9acc89720876ba9583c1dc988 (diff) | |
| download | django-rest-framework-d4b8e356b952137760bf33750b17895526d6151e.tar.bz2 | |
Merge branch '3.0-docs'
Diffstat (limited to 'docs/topics/3.0-announcement.md')
| -rw-r--r-- | docs/topics/3.0-announcement.md | 54 |
1 files changed, 49 insertions, 5 deletions
diff --git a/docs/topics/3.0-announcement.md b/docs/topics/3.0-announcement.md index 6a662326..9087e2ae 100644 --- a/docs/topics/3.0-announcement.md +++ b/docs/topics/3.0-announcement.md @@ -199,6 +199,33 @@ Alternatively if you want the errors to be against a specific field, use a dicti This ensures you can still write validation that compares all the input fields, but that marks the error against a particular field. +#### Removal of `transform_<field_name>`. + +The under-used `transform_<field_name>` on serializer classes is no longer provided. Instead you should just override `to_representation()` if you need to apply any modifications to the representation style. + +For example: + + def to_representation(self, instance): + ret = super(UserSerializer, self).to_representation(instance) + ret['username'] = ret['username'].lower() + return ret + +Dropping the extra point of API means there's now only one right way to do things. This helps with repetition and reinforcement of the core API, rather than having multiple differing approaches. + +If you absolutely need to preserve `transform_<field_name>` behavior, for example, in order to provide a simpler 2.x to 3.0 upgrade, you can use a mixin, or serializer base class that add the behavior back in. For example: + + class BaseModelSerializer(ModelSerializer): + """ + A custom ModelSerializer class that preserves 2.x style `transform_<field_name>` behavior. + """ + def to_representation(self, instance): + ret = super(BaseModelSerializer, self).to_representation(instance) + for key, value in ret.items(): + method = getattr(self, 'transform_' + key, None) + if method is not None: + ret[key] = method(value) + return ret + #### Differences between ModelSerializer validation and ModelForm. This change also means that we no longer use the `.full_clean()` method on model instances, but instead perform all validation explicitly on the serializer. This gives a cleaner separation, and ensures that there's no automatic validation behavior on `ModelSerializer` classes that can't also be easily replicated on regular `Serializer` classes. @@ -386,7 +413,11 @@ There are four methods that can be overridden, depending on what functionality y * `.to_representation()` - Override this to support serialization, for read operations. * `.to_internal_value()` - Override this to support deserialization, for write operations. -* `.create()` and `.update()` - Overide either or both of these to support saving instances. +* `.create()` and `.update()` - Override either or both of these to support saving instances. + +Because this class provides the same interface as the `Serializer` class, you can use it with the existing generic class based views exactly as you would for a regular `Serializer` or `ModelSerializer`. + +The only difference you'll notice when doing so is the `BaseSerializer` classes will not generate HTML forms in the browsable API. This is because the data they return does not include all the field information that would allow each field to be rendered into a suitable HTML input. ##### Read-only `BaseSerializer` classes. @@ -471,7 +502,7 @@ Here's a complete example of our previous `HighScoreSerializer`, that's been upd The `BaseSerializer` class is also useful if you want to implement new generic serializer classes for dealing with particular serialization styles, or for integrating with alternative storage backends. -The following class is an example of a generic serializer that can handle coercing aribitrary objects into primitive representations. +The following class is an example of a generic serializer that can handle coercing arbitrary objects into primitive representations. class ObjectSerializer(serializers.BaseSerializer): """ @@ -491,12 +522,12 @@ The following class is an example of a generic serializer that can handle coerci # Primitive types can be passed through unmodified. output[attribute_name] = attribute elif isinstance(attribute, list): - # Recursivly deal with items in lists. + # Recursively deal with items in lists. output[attribute_name] = [ self.to_representation(item) for item in attribute ] elif isinstance(attribute, dict): - # Recursivly deal with items in dictionarys. + # Recursively deal with items in dictionaries. output[attribute_name] = { str(key): self.to_representation(value) for key, value in attribute.items() @@ -544,6 +575,19 @@ The `default` argument is also available and always implies that the field is no The previous field implementations did not forcibly coerce returned values into the correct type in many cases. For example, an `IntegerField` would return a string output if the attribute value was a string. We now more strictly coerce to the correct return type, leading to more constrained and expected behavior. +#### Removal of `.validate()`. + +The `.validate()` method is now removed from field classes. This method was in any case undocumented and not public API. You should instead simply override `to_internal_value()`. + + class UppercaseCharField(serializers.CharField): + def to_internal_value(self, data): + value = super(UppercaseCharField, self).to_internal_value(data) + if value != value.upper(): + raise serializers.ValidationError('The input should be uppercase only.') + return value + +Previously validation errors could be raised in either `.to_native()` or `.validate()`, making it non-obvious which should be used. Providing only a single point of API ensures more repetition and reinforcement of the core API. + #### The `ListField` class. The `ListField` class has now been added. This field validates list input. It takes a `child` keyword argument which is used to specify the field used to validate each item in the list. For example: @@ -865,7 +909,7 @@ Or modify it on an individual serializer field, using the `coerce_to_string` key coerce_to_string=False ) -The default JSON renderer will return float objects for uncoerced `Decimal` instances. This allows you to easily switch between string or float representations for decimals depending on your API design needs. +The default JSON renderer will return float objects for un-coerced `Decimal` instances. This allows you to easily switch between string or float representations for decimals depending on your API design needs. ## Miscellaneous notes. |
