Tweaks to release notes

This commit is contained in:
Tom Christie 2014-11-07 20:44:12 +00:00
parent 59b30307e8
commit 93633c297c

View File

@ -27,8 +27,8 @@ Notable features of this new release include:
* Printable representations on serializers that allow you to inspect exactly what fields are present on the instance.
* Simple model serializers that are vastly easier to understand and debug, and that make it easy to switch between the implicit `ModelSerializer` class and the explicit `Serializer` class.
* A new `BaseSerializer` class, making it easier to write serializers for alternative storage backends, or to completely customize your serialization and validation logic.
* A cleaner fields API plus new `ListField` and `MultipleChoiceField` classes.
* Super simple default implementations for the generic views.
* A cleaner fields API including new classes such as `ListField` and `MultipleChoiceField`.
* [Super simple default implementations][mixins.py] for the generic views.
* Support for overriding how validation errors are handled by your API.
* A metadata API that allows you to customize how `OPTIONS` requests are handled by your API.
* A more compact JSON output with unicode style encoding turned on by default.
@ -70,7 +70,7 @@ Previously the serializers used a two-step object creation, as follows:
This style is in-line with how the `ModelForm` class works in Django, but is problematic for a number of reasons:
* Some data, such as many-to-many relationships, cannot be added to the object instance until after it has been saved. This type of data needed to be hidden in some undocumented state on the object instance, or kept as state on the serializer instance so that it could be used when `.save()` is called.
* Instantiating model instances directly means that you cannot use model manager classes for instance creation, eg `ExampleModel.objects.create(...)`. Manager classes are an excellent layer at which to enforce business logic and application-level data constraints.
* Instantiating model instances directly means that you cannot use model manager classes for instance creation, e.g. `ExampleModel.objects.create(...)`. Manager classes are an excellent layer at which to enforce business logic and application-level data constraints.
* The two step process makes it unclear where to put deserialization logic. For example, should extra attributes such as the current user get added to the instance during object creation or during object save?
We now use single-step object creation, like so:
@ -184,7 +184,7 @@ This ensures you can still write validation that compares all the input fields,
#### 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 behaviour on `ModelSerializer` classes that can't also be easily replicated on regular `Serializer` classes.
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.
It's important to note that this change also means that the model `.clean()` method will not be called as part of serializer validation, as it would be if using a `ModelForm`. Use the serializer `.validate()` method to perform a final validation step on incoming data where required.
@ -219,7 +219,7 @@ If you try to use a writable nested serializer without writing a custom `create(
>>>
>>> serializer = UserSerializer(data=data)
>>> serializer.save()
AssertionError: The `.create()` method does not suport nested writable fields by default. Write an explicit `.create()` method for serializer `UserSerializer`, or set `read_only=True` on nested serializer fields.
AssertionError: The `.create()` method does not support nested writable fields by default. Write an explicit `.create()` method for serializer `UserSerializer`, or set `read_only=True` on nested serializer fields.
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.
@ -274,7 +274,7 @@ The `write_only_fields` option on `ModelSerializer` has been moved to `PendingDe
model = MyModel
fields = ('id', 'email', 'notes', 'is_admin')
extra_kwargs = {
'is_admin': {'write_only': True}
'is_admin': {'write_only': True}
}
Alternatively, specify the field explicitly on the serializer class:
@ -321,8 +321,8 @@ With `ModelSerializer` you can now specify field names in the `fields` option th
to_email = models.EmailField()
message = models.CharField(max_length=1000)
def expiry_date(self):
return self.created + datetime.timedelta(days=30)
def expiry_date(self):
return self.created + datetime.timedelta(days=30)
You can include `expiry_date` as a field option on a `ModelSerializer` class.
@ -584,7 +584,7 @@ Previously relational fields that were explicitly declared on a serializer class
This code *would be valid* in `2.4.3`:
class AccountSerializer(serializers.ModelSerializer):
organisations = serializers.SlugRelatedField(slug_field='name')
organizations = serializers.SlugRelatedField(slug_field='name')
class Meta:
model = Account
@ -593,7 +593,7 @@ However this code *would not be valid* in `2.4.3`:
# Missing `queryset`
class AccountSerializer(serializers.Serializer):
organisations = serializers.SlugRelatedField(slug_field='name')
organizations = serializers.SlugRelatedField(slug_field='name')
def restore_object(self, attrs, instance=None):
# ...
@ -602,9 +602,9 @@ The queryset argument is now always required for writable relational fields.
This removes some magic and makes it easier and more obvious to move between implicit `ModelSerializer` classes and explicit `Serializer` classes.
class AccountSerializer(serializers.ModelSerializer):
organisations = serializers.SlugRelatedField(
organizations = serializers.SlugRelatedField(
slug_field='name',
queryset=Organisation.objects.all()
queryset=Organization.objects.all()
)
class Meta:
@ -637,7 +637,7 @@ The following usage will *now raise an error*:
#### The `UniqueValidator` and `UniqueTogetherValidator` classes.
REST framework now provides two new validators that allow you to ensure field uniqueness, while still using a completely explicit `Serializer` class instead of using `ModelSerializer`.
REST framework now provides new validators that allow you to ensure field uniqueness, while still using a completely explicit `Serializer` class instead of using `ModelSerializer`.
The `UniqueValidator` should be applied to a serializer field, and takes a single `queryset` argument.
@ -645,11 +645,11 @@ The `UniqueValidator` should be applied to a serializer field, and takes a singl
from rest_framework.validators import UniqueValidator
class OrganizationSerializer(serializers.Serializer):
url = serializers.HyperlinkedIdentityField(view_name='organisation_detail')
url = serializers.HyperlinkedIdentityField(view_name='organization_detail')
created = serializers.DateTimeField(read_only=True)
name = serializers.CharField(
max_length=100,
validators=UniqueValidator(queryset=Organisation.objects.all())
validators=UniqueValidator(queryset=Organization.objects.all())
)
The `UniqueTogetherValidator` should be applied to a serializer, and takes a `queryset` argument and a `fields` argument which should be a list or tuple of field names.
@ -664,6 +664,10 @@ The `UniqueTogetherValidator` should be applied to a serializer, and takes a `qu
fields=('category', 'position')
)]
#### The `UniqueForDateValidator` classes.
**TODO: Needs documenting.**
## Generic views
#### Simplification of view logic.
@ -700,7 +704,7 @@ I would personally recommend that developers treat view instances as immutable o
#### PUT as create.
Allowing `PUT` as create operations is problematic, as it necessarily exposes information about the existence or non-existance of objects. It's also not obvious that transparently allowing re-creating of previously deleted instances is necessarily a better default behavior than simply returning `404` responses.
Allowing `PUT` as create operations is problematic, as it necessarily exposes information about the existence or non-existence of objects. It's also not obvious that transparently allowing re-creating of previously deleted instances is necessarily a better default behavior than simply returning `404` responses.
Both styles "`PUT` as 404" and "`PUT` as create" can be valid in different circumstances, but we've now opted for the 404 behavior as the default, due to it being simpler and more obvious.
@ -718,6 +722,10 @@ Behavior for dealing with `OPTIONS` requests was previously built directly into
This makes it far easier to use a different style for `OPTIONS` responses throughout your API, and makes it possible to create third-party metadata policies.
## Serializers as HTML forms
**TODO: Document this.**
## API style
There are some improvements in the default style we use in our API responses.
@ -817,6 +825,7 @@ The default JSON renderer will return float objects for uncoerced `Decimal` inst
The 3.1 release is planned to address improvements in the following components:
* Public API for using serializers as HTML forms.
* Request parsing, mediatypes & the implementation of the browsable API.
* Introduction of a new pagination API.
* Better support for API versioning.
@ -824,3 +833,5 @@ The 3.1 release is planned to address improvements in the following components:
The 3.2 release is planned to introduce an alternative admin-style interface to the browsable API.
You can follow development on the GitHub site, where we use [milestones to indicate planning timescales](https://github.com/tomchristie/django-rest-framework/milestones).
[mixins.py]: https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/mixins.py