django-rest-framework/docs/topics/3.0-announcement.md
2014-09-19 14:59:59 +01:00

7.5 KiB

THIS DOCUMENT IS CURRENTLY A WORK IN PROGRESS

See the Version 3.0 GitHub issue for more details.

REST framework 3.0

Note incremental nature, discuss upgrading.

Motivation

TODO


Request objects

The request.data property.

TODO

The parser API.

TODO

Serializers

Single-step object creation.

TODO: Drop .restore_object(), use .create() and .update() which should save the instance.

TODO: Drop.object, use .validated_data or get the instance with .save().

The BaseSerializer class.

TODO

Always use fields, not exclude.

The exclude option is no longer available. You should use the more explicit fields option instead.

The extra_kwargs option.

The read_only_fields and write_only_fields options have been removed and replaced with a more generic extra_kwargs.

class MySerializer(serializer.ModelSerializer):
    class Meta:
        model = MyModel
        fields = ('id', 'email', 'notes', 'is_admin')
        extra_kwargs = {
        	'is_admin': {'read_only': True}
        }

Alternatively, specify the field explicitly on the serializer class:

class MySerializer(serializer.ModelSerializer):
    is_admin = serializers.BooleanField(read_only=True)

    class Meta:
        model = MyModel
        fields = ('id', 'email', 'notes', 'is_admin')

Changes to HyperlinkedModelSerializer.

The view_name and lookup_field options have been removed. They are no longer required, as you can use the extra_kwargs argument instead:

class MySerializer(serializer.HyperlinkedModelSerializer):
    class Meta:
        model = MyModel
        fields = ('url', 'email', 'notes', 'is_admin')
        extra_kwargs = {
        	'url': {'lookup_field': 'uuid'}
        }

Alternatively, specify the field explicitly on the serializer class:

class MySerializer(serializer.HyperlinkedModelSerializer):
    url = serializers.HyperlinkedIdentityField(
        view_name='mymodel-detail',
        lookup_field='uuid'
    )

    class Meta:
        model = MyModel
        fields = ('url', 'email', 'notes', 'is_admin')

Fields for model methods and properties.

You can now specify field names in the fields option that refer to model methods or properties. For example, suppose you have the following model:

class Invitation(models.Model):
    created = models.DateTimeField()
    to_email = models.EmailField()
    message = models.CharField(max_length=1000)

	def expiry_date(self):
	    return self.created + datetime.timedelta(days=30)

You can include expiry_date as a field option on a ModelSerializer class.

class InvitationSerializer(serializers.ModelSerializer):
    class Meta:
        model = Invitation
        fields = ('to_email', 'message', 'expiry_date')

These fields will be mapped to serializers.ReadOnlyField() instances.

>>> serializer = InvitationSerializer()
>>> print repr(serializer)
InvitationSerializer():
    to_email = EmailField(max_length=75)
    message = CharField(max_length=1000)
    expiry_date = ReadOnlyField()

Serializer fields

The Field and ReadOnly field classes.

TODO

Coercing output types.

TODO

The ListSerializer class.

TODO

The MultipleChoiceField class.

TODO

Changes to the custom field API.

TODO to_representation, to_internal_value.

Explicit querysets required on relational fields.

TODO

Optional argument to SerializerMethodField.

TODO

Generic views

Simplification of view logic.

TODO

Removal of pre/post save hooks.

The following method hooks no longer exist on the new, simplified, generic views: pre_save, post_save, pre_delete, post_delete.

If you do need custom behavior, you might choose to instead override the .save() method on your serializer class. For example:

def save(self, *args, **kwargs):
    instance = super(MySerializer).save(*args, **kwarg)
    send_email(instance.to_email, instance.message)
	return instance

Alternatively write your view logic exlpicitly, or tie your pre/post save behavior into the model class or model manager.

Removal of view attributes.

The .object and .object_list attributes are no longer set on the view instance. Treating views as mutable object instances that store state during the processing of the view tends to be poor design, and can lead to obscure flow logic.

I would personally recommend that developers treat view instances as immutable objects in their application code.

PUT as create.

TODO

API style

There are some improvements in the default style we use in our API responses.

Unicode JSON by default.

Unicode JSON is now the default. The UnicodeJSONRenderer class no longer exists, and the UNICODE_JSON setting has been added. To revert this behavior use the new setting:

REST_FRAMEWORK = {
    'UNICODE_JSON': False
}

Compact JSON by default.

We now output compact JSON in responses by default. For example, we return:

{"email":"amy@example.com","is_admin":true}

Instead of the following:

{"email": "amy@example.com", "is_admin": true}

The COMPACT_JSON setting has been added, and can be used to revert this behavior if needed:

REST_FRAMEWORK = {
    'COMPACT_JSON': False
}

Throttle headers using Retry-After.

The custom X-Throttle-Wait-Second header has now been dropped in favor of the standard Retry-After header. You can revert this behavior if needed by writing a custom exception handler for your application.

Date and time objects as ISO-8859-1 strings in serializer data.

Date and Time objects are now coerced to strings by default in the serializer output. Previously they were returned as Date, Time and DateTime objects, and later coerced to strings by the renderer.

You can modify this behavior globally by settings the existing DATE_FORMAT, DATETIME_FORMAT and TIME_FORMAT settings keys. Setting these values to None instead of their default value of 'iso-8859-1' will result in native objects being returned in serializer data.

REST_FRAMEWORK = {
    # Return native `Date` and `Time` objects in `serializer.data`
    'DATETIME_FORMAT': None
    'DATE_FORMAT': None
    'TIME_FORMAT': None
}

You can also modify serializer fields individually, using the date_format, time_format and datetime_format arguments:

# Return `DateTime` instances in `serializer.data`, not strings.
created = serializers.DateTimeField(format=None)

Decimals as strings in serializer data.

Decimals are now coerced to strings by default in the serializer output. Previously they were returned as Decimal objects, and later coerced to strings by the renderer.

You can modify this behavior globally by using the COERCE_DECIMAL_TO_STRING settings key.

REST_FRAMEWORK = {
    'COERCE_DECIMAL_TO_STRING': False
}

Or modify it on an individual serializer field, using the corece_to_string keyword argument.

# Return `Decimal` instances in `serializer.data`, not strings.
amount = serializers.DecimalField(
    max_digits=10,
    decimal_places=2,
    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.