Update release notes

This commit is contained in:
Tom Christie 2014-09-29 12:57:05 +01:00
parent d2d412993f
commit 4798df52df
2 changed files with 39 additions and 6 deletions

View File

@ -146,7 +146,41 @@ The corresponding code would now look like this:
extras = {'user': request.user} # Include the user when saving. extras = {'user': request.user} # Include the user when saving.
serializer.save(extras=extras) serializer.save(extras=extras)
#### Printable serializer reprensentations. #### Limitations of ModelSerializer validation.
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 seperation, and ensures that there's no automatic validation behavior on `ModelSerializer` classes that can't also be easily replicated on regular `Serializer` classes.
This change comes with the following limitations:
* The model `.clean()` method will not be called as part of serializer validation. Use the serializer `.validate()` method to perform a final validation step on incoming data where required.
* The `.unique_for_date`, `.unique_for_month` and `.unique_for_year` options on model fields are not automatically validated. Again, you'll need to handle these explicitly on the serializer if required.
#### Writable nested serialization.
REST framework 2.x attempted to automatically support writable nested serialization, but the behavior was complex and non-obvious. Attempting to automatically handle these case is problematic:
* There can be complex dependancies involved in order of saving multiple related model instances.
* It's unclear what behavior the user should expect when related models are passed `None` data.
* It's unclear how the user should expect to-many relationships to handle updates, creations and deletions of multiple records.
Using the `depth` option on `ModelSerializer` will now create **read-only nested serializers** by default. To use writable nested serialization you'll want to declare a nested field on the serializer class, and write the `create()` and/or `update()` methods explicitly.
class UserSerializer(serializers.ModelSerializer):
profile = ProfileSerializer()
class Meta:
model = User
fields = ('username', 'email', 'profile')
def create(self, validated_data):
profile_data = validated_data.pop['profile']
user = User.objects.create(**validated_data)
profile = Profile.objects.create(user=user, **profile_data)
return user
The single-step object creation makes this far simpler and more obvious than the previous `.restore_object()` behavior.
#### Printable serializer representations.
Serializer instances now support a printable representation that allows you to inspect the fields present on the instance. Serializer instances now support a printable representation that allows you to inspect the fields present on the instance.
@ -279,7 +313,7 @@ There are four mathods that can be overriding, depending on what functionality y
* `.to_internal_value()` - Override this to support deserialization, for write 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()` - Overide either or both of these to support saving instances.
##### Read-only serializers. ##### Read-only `BaseSerializer` classes.
To implement a read-only serializer using the `BaseSerializer` class, we just need to override the `.to_representation()` method. Let's take a look at an example using a simple Django model: To implement a read-only serializer using the `BaseSerializer` class, we just need to override the `.to_representation()` method. Let's take a look at an example using a simple Django model:
@ -313,7 +347,7 @@ Or use it to serialize multiple instances:
serializer = HighScoreSerializer(queryset, many=True) serializer = HighScoreSerializer(queryset, many=True)
return Response(serializer.data) return Response(serializer.data)
##### Read-write serializers. ##### Read-write `BaseSerializer` classes.
To create a read-write serializer we first need to implement a `.to_internal_value()` method. This method returns the validated values that will be used to construct the object instance, and may raise a `ValidationError` if the supplied data is in an incorrect format. To create a read-write serializer we first need to implement a `.to_internal_value()` method. This method returns the validated values that will be used to construct the object instance, and may raise a `ValidationError` if the supplied data is in an incorrect format.
@ -358,9 +392,9 @@ Here's a complete example of our previous `HighScoreSerializer`, that's been upd
def create(self, validated_data): def create(self, validated_data):
return HighScore.objects.create(**validated_data) return HighScore.objects.create(**validated_data)
#### Creating new base classes with `BaseSerializer`. #### Creating new generic serializers with `BaseSerializer`.
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 different storage backends. 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 primative representations. The following class is an example of a generic serializer that can handle coercing aribitrary objects into primative representations.

View File

@ -98,7 +98,6 @@ class TestUniquenessTogetherValidation(TestCase):
""" """
data = {'race_name': 'example', 'position': 2} data = {'race_name': 'example', 'position': 2}
serializer = UniquenessTogetherSerializer(data=data) serializer = UniquenessTogetherSerializer(data=data)
print serializer.validators
assert not serializer.is_valid() assert not serializer.is_valid()
assert serializer.errors == { assert serializer.errors == {
'non_field_errors': [ 'non_field_errors': [