From a8a3fedb5c52cc62c6ecf59c4138e9a6ecf04806 Mon Sep 17 00:00:00 2001 From: tanwanirahul Date: Fri, 19 Dec 2014 20:16:46 +0530 Subject: Add url_path documention for detail_route decorator --- docs/tutorial/6-viewsets-and-routers.md | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docs') diff --git a/docs/tutorial/6-viewsets-and-routers.md b/docs/tutorial/6-viewsets-and-routers.md index cf37a260..8e4e22f0 100644 --- a/docs/tutorial/6-viewsets-and-routers.md +++ b/docs/tutorial/6-viewsets-and-routers.md @@ -53,6 +53,8 @@ Notice that we've also used the `@detail_route` decorator to create a custom act Custom actions which use the `@detail_route` decorator will respond to `GET` requests. We can use the `methods` argument if we wanted an action that responded to `POST` requests. +The URLs for custom actions by default depends on the method name itself. If you want to change the way url should be constructed, you can use `url_path` parameter of `@detail_route` and provide the string value for the same. + ## Binding ViewSets to URLs explicitly The handler methods only get bound to the actions when we define the URLConf. -- cgit v1.2.3 From 6aa0e307c99d0c17d7c48f2416472c7dbdcbbf8f Mon Sep 17 00:00:00 2001 From: Rahul Date: Fri, 19 Dec 2014 20:31:21 +0530 Subject: Added documentation about url_path parameter for custom actions. --- docs/api-guide/routers.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'docs') diff --git a/docs/api-guide/routers.md b/docs/api-guide/routers.md index 61a476b8..63b8b59a 100644 --- a/docs/api-guide/routers.md +++ b/docs/api-guide/routers.md @@ -68,6 +68,24 @@ The following URL pattern would additionally be generated: * URL pattern: `^users/{pk}/set_password/$` Name: `'user-set-password'` +If you did not like the default URL generated for your custom action, you could use `url_path` parameter with `@detail_route` or `@list_route` to customize it. + +For example, if you want to change the URL for our custom action to `^users/{pk}/change-password/$`, you could write: + + from myapp.permissions import IsAdminOrIsSelf + from rest_framework.decorators import detail_route + + class UserViewSet(ModelViewSet): + ... + + @detail_route(methods=['post'], permission_classes=[IsAdminOrIsSelf], url_path='change-password') + def set_password(self, request, pk=None): + ... + +Above example would instead generate following URL pattern: + +* URL pattern: `^users/{pk}/change-password/$` Name: `'user-change-password'` + For more information see the viewset documentation on [marking extra actions for routing][route-decorators]. # API Guide -- cgit v1.2.3 From b4a3e7f64096ea7106ff0d622bdf1c6e2e4e2895 Mon Sep 17 00:00:00 2001 From: Rahul Date: Fri, 19 Dec 2014 21:20:19 +0530 Subject: Updates url_path info per suggestion --- docs/api-guide/routers.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs') diff --git a/docs/api-guide/routers.md b/docs/api-guide/routers.md index 63b8b59a..87b6f15a 100644 --- a/docs/api-guide/routers.md +++ b/docs/api-guide/routers.md @@ -68,7 +68,7 @@ The following URL pattern would additionally be generated: * URL pattern: `^users/{pk}/set_password/$` Name: `'user-set-password'` -If you did not like the default URL generated for your custom action, you could use `url_path` parameter with `@detail_route` or `@list_route` to customize it. +If you do not want to use the default URL generated for your custom action, you can instead use the url_path parameter to customize it. For example, if you want to change the URL for our custom action to `^users/{pk}/change-password/$`, you could write: @@ -82,7 +82,7 @@ For example, if you want to change the URL for our custom action to `^users/{pk} def set_password(self, request, pk=None): ... -Above example would instead generate following URL pattern: +The above example would now generate the following URL pattern: * URL pattern: `^users/{pk}/change-password/$` Name: `'user-change-password'` -- cgit v1.2.3 From 8f0fef4b75f5c999c13b5d37a263da3a3388142e Mon Sep 17 00:00:00 2001 From: Rahul Date: Fri, 19 Dec 2014 21:22:10 +0530 Subject: Updated documentation on url_path per suggestions. --- docs/tutorial/6-viewsets-and-routers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/tutorial/6-viewsets-and-routers.md b/docs/tutorial/6-viewsets-and-routers.md index 8e4e22f0..d2ee1102 100644 --- a/docs/tutorial/6-viewsets-and-routers.md +++ b/docs/tutorial/6-viewsets-and-routers.md @@ -53,7 +53,7 @@ Notice that we've also used the `@detail_route` decorator to create a custom act Custom actions which use the `@detail_route` decorator will respond to `GET` requests. We can use the `methods` argument if we wanted an action that responded to `POST` requests. -The URLs for custom actions by default depends on the method name itself. If you want to change the way url should be constructed, you can use `url_path` parameter of `@detail_route` and provide the string value for the same. +The URLs for custom actions by default depend on the method name itself. If you want to change the way url should be constructed, you can include url_path as a decorator keyword argument. ## Binding ViewSets to URLs explicitly -- cgit v1.2.3 From 48d15f6ff8a13aafd5b4977c8d1b4b7fe70b4f6a Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 19 Dec 2014 16:58:35 +0000 Subject: Stub out the documentation --- docs/api-guide/serializers.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'docs') diff --git a/docs/api-guide/serializers.md b/docs/api-guide/serializers.md index b9f0e7bc..4d3dfa31 100644 --- a/docs/api-guide/serializers.md +++ b/docs/api-guide/serializers.md @@ -567,6 +567,32 @@ The inner `Meta` class on serializers is not inherited from parent classes by de Typically we would recommend *not* using inheritance on inner Meta classes, but instead declaring all options explicitly. +## Advanced `ModelSerializer` usage + +The ModelSerializer class also exposes an API that you can override in order to alter how serializer fields are automatically determined when instantiating the serializer. + +#### `.serializer_field_mapping` + +A mapping of Django model classes to REST framework serializer classes. You can override this mapping to alter the default serializer classes that should be used for each model class. + +#### `.serializer_relational_field` + +This property should be the serializer field class, that is used for relational fields by default. For `ModelSerializer` this defaults to `PrimaryKeyRelatedField`. For `HyperlinkedModelSerializer` this defaults to `HyperlinkedRelatedField`. + +#### The build field methods + +#### `build_standard_field(**kwargs)` + +#### `build_relational_field(**kwargs)` + +#### `build_nested_field(**kwargs)` + +#### `build_property_field(**kwargs)` + +#### `build_url_field(**kwargs)` + +#### `build_unknown_field(**kwargs)` + --- # HyperlinkedModelSerializer -- cgit v1.2.3 From 2a1485e00943b8280245d19e1e1f8514b1ef18ea Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 19 Dec 2014 21:32:43 +0000 Subject: Final bits of docs for ModelSerializer fields API --- docs/api-guide/serializers.md | 57 +++++++++++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 13 deletions(-) (limited to 'docs') diff --git a/docs/api-guide/serializers.md b/docs/api-guide/serializers.md index 4d3dfa31..dcbbd5f2 100644 --- a/docs/api-guide/serializers.md +++ b/docs/api-guide/serializers.md @@ -457,7 +457,7 @@ To do so, open the Django shell, using `python manage.py shell`, then import the name = CharField(allow_blank=True, max_length=100, required=False) owner = PrimaryKeyRelatedField(queryset=User.objects.all()) -## Specifying which fields should be included +## Specifying which fields to include If you only want a subset of the default fields to be used in a model serializer, you can do so using `fields` or `exclude` options, just as you would with a `ModelForm`. @@ -499,7 +499,7 @@ You can add extra fields to a `ModelSerializer` or override the default fields b Extra fields can correspond to any property or callable on the model. -## Specifying which fields should be read-only +## Specifying read only fields You may wish to specify multiple fields as read-only. Instead of adding each field explicitly with the `read_only=True` attribute, you may use the shortcut Meta option, `read_only_fields`. @@ -528,7 +528,7 @@ Please review the [Validators Documentation](/api-guide/validators/) for details --- -## Specifying additional keyword arguments for fields. +## Additional keyword arguments There is also a shortcut allowing you to specify arbitrary additional keyword arguments on fields, using the `extra_kwargs` option. Similarly to `read_only_fields` this means you do not need to explicitly declare the field on the serializer. @@ -567,31 +567,62 @@ The inner `Meta` class on serializers is not inherited from parent classes by de Typically we would recommend *not* using inheritance on inner Meta classes, but instead declaring all options explicitly. -## Advanced `ModelSerializer` usage +## Customizing field mappings The ModelSerializer class also exposes an API that you can override in order to alter how serializer fields are automatically determined when instantiating the serializer. -#### `.serializer_field_mapping` +Normally if a `ModelSerializer` does not generate the fields you need by default the you should either add them to the class explicitly, or simply use a regular `Serializer` class instead. However in some cases you may want to create a new base class that defines how the serializer fields are created for any given model. + +### `.serializer_field_mapping` A mapping of Django model classes to REST framework serializer classes. You can override this mapping to alter the default serializer classes that should be used for each model class. -#### `.serializer_relational_field` +### `.serializer_relational_field` This property should be the serializer field class, that is used for relational fields by default. For `ModelSerializer` this defaults to `PrimaryKeyRelatedField`. For `HyperlinkedModelSerializer` this defaults to `HyperlinkedRelatedField`. -#### The build field methods +### The field_class and field_kwargs API + +The following methods are called to determine the class and keyword arguments for each field that should be automatically included on the serializer. Each of these methods should return a two tuple of `(field_class, field_kwargs)`. + +### `.build_standard_field(self, field_name, model_field)` + +Called to generate a serializer field that maps to a standard model field. + +The default implementation returns a serializer class based on the `serializer_field_mapping` attribute. + +### `.build_relational_field(self, field_name, relation_info)` + +Called to generate a serializer field that maps to a relational model field. + +The default implementation returns a serializer class based on the `serializer_relational_field` attribute. + +The `relation_info` argument is a named tuple, that contains `model_field`, `related_model`, `to_many` and `has_through_model` properties. + +### `.build_nested_field(self, field_name, relation_info, nested_depth)` + +Called to generate a serializer field that maps to a relational model field, when the `depth` option has been set. + +The default implementation dynamically creates a nested serializer class based on either `ModelSerializer` or `HyperlinkedModelSerializer`. + +The `nested_depth` will be the value of the `depth` option, minus one. + +The `relation_info` argument is a named tuple, that contains `model_field`, `related_model`, `to_many` and `has_through_model` properties. + +### `.build_property_field(self, field_name, model_class)` -#### `build_standard_field(**kwargs)` +Called to generate a serializer field that maps to a property or zero-argument method on the model class. -#### `build_relational_field(**kwargs)` +The default implementation returns a `ReadOnlyField` class. -#### `build_nested_field(**kwargs)` +### `.build_url_field(self, field_name, model_class)` -#### `build_property_field(**kwargs)` +Called to generate a serializer field for the serializer's own `url` field. The default implementation returns a `HyperlinkedIdentityField` class. -#### `build_url_field(**kwargs)` +### `.build_unknown_field(self, field_name, model_class)` -#### `build_unknown_field(**kwargs)` +Called when the field name did not map to any model field or model property. +The default implementation raises an error, although subclasses may customize this behavior. --- -- cgit v1.2.3 From 35696748603665526be7947e918d41856644ec52 Mon Sep 17 00:00:00 2001 From: Brian Stearns Date: Sun, 21 Dec 2014 18:53:35 -0500 Subject: use of double quotes broke the code highlighting. --- docs/api-guide/fields.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/api-guide/fields.md b/docs/api-guide/fields.md index f06db56c..946e355d 100644 --- a/docs/api-guide/fields.md +++ b/docs/api-guide/fields.md @@ -480,7 +480,7 @@ Let's look at an example of serializing a class that represents an RGB color val class ColorField(serializers.Field): """ - Color objects are serialized into "rgb(#, #, #)" notation. + Color objects are serialized into 'rgb(#, #, #)' notation. """ def to_representation(self, obj): return "rgb(%d, %d, %d)" % (obj.red, obj.green, obj.blue) -- cgit v1.2.3 From 18687f075d9fb998b82c6fb8f6cb37eb1ed7e5bf Mon Sep 17 00:00:00 2001 From: Matías Lang Date: Tue, 23 Dec 2014 12:22:10 -0300 Subject: Documented an optional argument of HyperlinkedIdentityField lookup_url_kwarg argument of HyperlinkedIdentityField wasn't documented--- docs/api-guide/relations.md | 1 + 1 file changed, 1 insertion(+) (limited to 'docs') diff --git a/docs/api-guide/relations.md b/docs/api-guide/relations.md index e56db229..50e3b7b5 100644 --- a/docs/api-guide/relations.md +++ b/docs/api-guide/relations.md @@ -231,6 +231,7 @@ This field is always read-only. * `view_name` - The view name that should be used as the target of the relationship. If you're using [the standard router classes][routers] this will be a string with the format `-detail`. **required**. * `lookup_field` - The field on the target that should be used for the lookup. Should correspond to a URL keyword argument on the referenced view. Default is `'pk'`. +* `lookup_url_kwarg` - The name of the keyword argument defined in the URL conf that corresponds to the lookup field. Defaults to using the same value as `lookup_field`. * `format` - If using format suffixes, hyperlinked fields will use the same format suffix for the target unless overridden by using the `format` argument. --- -- cgit v1.2.3 From 00531ec937206e7e0af949c67872c915d0752b5a Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 26 Dec 2014 15:48:16 +0000 Subject: Release notes on non-text detail arguments. Closes #2341. --- docs/topics/3.0-announcement.md | 1 + 1 file changed, 1 insertion(+) (limited to 'docs') diff --git a/docs/topics/3.0-announcement.md b/docs/topics/3.0-announcement.md index 0710766f..68d24782 100644 --- a/docs/topics/3.0-announcement.md +++ b/docs/topics/3.0-announcement.md @@ -940,6 +940,7 @@ The default JSON renderer will return float objects for un-coerced `Decimal` ins * The serializer `ChoiceField` does not currently display nested choices, as was the case in 2.4. This will be address as part of 3.1. * Due to the new templated form rendering, the 'widget' option is no longer valid. This means there's no easy way of using third party "autocomplete" widgets for rendering select inputs that contain a large number of choices. You'll either need to use a regular select or a plain text input. We may consider addressing this in 3.1 or 3.2 if there's sufficient demand. * Some of the default validation error messages were rewritten and might no longer be pre-translated. You can still [create language files with Django][django-localization] if you wish to localize them. +* `APIException` subclasses could previously take could previously take any arbitrary type in the `detail` argument. These exceptions now use translatable text strings, and as a result call `force_text` on the `detail` argument, which *must be a string*. If you need complex arguments to an `APIException` class, you should subclass it and override the `__init__()` method. Typically you'll instead want to use a custom exception handler to provide for non-standard error responses. --- -- cgit v1.2.3 From 5b5652594a9c000d8e925d35efa03be27c28c077 Mon Sep 17 00:00:00 2001 From: Rocky Meza Date: Fri, 26 Dec 2014 22:24:31 -0700 Subject: Typo manger => manager --- docs/api-guide/serializers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/api-guide/serializers.md b/docs/api-guide/serializers.md index b9f0e7bc..f88ec51f 100644 --- a/docs/api-guide/serializers.md +++ b/docs/api-guide/serializers.md @@ -384,7 +384,7 @@ This manager class now more nicely encapsulates that user instances and profile has_support_contract=validated_data['profile']['has_support_contract'] ) -For more details on this approach see the Django documentation on [model managers](model-managers), and [this blogpost on using model and manger classes](encapsulation-blogpost). +For more details on this approach see the Django documentation on [model managers](model-managers), and [this blogpost on using model and manager classes](encapsulation-blogpost). ## Dealing with multiple objects -- cgit v1.2.3 From a636320ff3b381a6d7d8685f1b4fba8bdd6c8b94 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Sun, 28 Dec 2014 11:02:19 +0000 Subject: Add import notes in docs. Closes #2357 --- docs/api-guide/generic-views.md | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'docs') diff --git a/docs/api-guide/generic-views.md b/docs/api-guide/generic-views.md index f5bbdfdd..6374e305 100755 --- a/docs/api-guide/generic-views.md +++ b/docs/api-guide/generic-views.md @@ -214,6 +214,8 @@ You won't typically need to override the following methods, although you might n The mixin classes provide the actions that are used to provide the basic view behavior. Note that the mixin classes provide action methods rather than defining the handler methods, such as `.get()` and `.post()`, directly. This allows for more flexible composition of behavior. +The mixin classes can be imported from `rest_framework.mixins`. + ## ListModelMixin Provides a `.list(request, *args, **kwargs)` method, that implements listing a queryset. @@ -258,6 +260,8 @@ If an object is deleted this returns a `204 No Content` response, otherwise it w The following classes are the concrete generic views. If you're using generic views this is normally the level you'll be working at unless you need heavily customized behavior. +The view classes can be imported from `rest_framework.generics`. + ## CreateAPIView Used for **create-only** endpoints. -- cgit v1.2.3 From 8dc95ee22181de6e38c7187426bca9fcee9d7927 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Sun, 28 Dec 2014 11:24:49 +0000 Subject: Add notes on include and namespacing. Closes #2335. --- docs/api-guide/routers.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'docs') diff --git a/docs/api-guide/routers.md b/docs/api-guide/routers.md index 6819adb6..3a8a8f6c 100644 --- a/docs/api-guide/routers.md +++ b/docs/api-guide/routers.md @@ -49,6 +49,38 @@ This means you'll need to explicitly set the `base_name` argument when registeri --- +### Using `include` with routers + +The `.urls` attribute on a router instance is simply a standard list of URL patterns. There are a number of different styles for how you can include these URLs. + +For example, you can append `router.urls` to a list of existing views… + + router = routers.SimpleRouter() + router.register(r'users', UserViewSet) + router.register(r'accounts', AccountViewSet) + + urlpatterns = [ + url(r'^forgot-password/$, ForgotPasswordFormView.as_view(), + ] + + urlpatterns += router.urls + +Alternatively you can use Django's `include` function, like so… + + urlpatterns = [ + url(r'^forgot-password/$, ForgotPasswordFormView.as_view(), + url(r'^', include(router.urls)) + ] + +Router URL patterns can also be namespaces. + + urlpatterns = [ + url(r'^forgot-password/$, ForgotPasswordFormView.as_view(), + url(r'^api/', include(router.urls, namespace='api')) + ] + +If using namespacing with hyperlinked serializers you'll also need to ensure that any `view_name` parameters on the serializers correctly reflect the namespace. In the example above you'd need to include a parameter such as `view_name='api:user-detail'` for serializer fields hyperlinked to the user detail view. + ### Extra link and actions Any methods on the viewset decorated with `@detail_route` or `@list_route` will also be routed. -- cgit v1.2.3 From d8e66970a11ec2d4b66f0cf56950f2cc83e83224 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Sun, 28 Dec 2014 12:14:07 +0000 Subject: Note on using i18n_patterns with format_suffix_patterns. Closes #2278. --- docs/api-guide/format-suffixes.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'docs') diff --git a/docs/api-guide/format-suffixes.md b/docs/api-guide/format-suffixes.md index 20c1e995..35dbcd39 100644 --- a/docs/api-guide/format-suffixes.md +++ b/docs/api-guide/format-suffixes.md @@ -55,6 +55,18 @@ The name of the kwarg used may be modified by using the `FORMAT_SUFFIX_KWARG` se Also note that `format_suffix_patterns` does not support descending into `include` URL patterns. +### Using with `i18n_patterns` + +If using the `i18n_patterns` function provided by Django, as well as `format_suffix_patterns` you should make sure that the `i18n_patterns` function is applied as the final, or outermost function. For example: + + url patterns = [ + … + ] + + urlpatterns = i18n_patterns( + format_suffix_patterns(urlpatterns, allowed=['json', 'html']) + ) + --- ## Accept headers vs. format suffixes -- cgit v1.2.3 From 5d8c45681a945b955d9336b0fd1e4ebccf0df895 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Sun, 28 Dec 2014 18:48:42 +0000 Subject: Update copryright for 2015. Closes #2247. --- docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/index.md b/docs/index.md index 8a96fc9f..55129df1 100644 --- a/docs/index.md +++ b/docs/index.md @@ -235,7 +235,7 @@ Send a description of the issue via email to [rest-framework-security@googlegrou ## License -Copyright (c) 2011-2014, Tom Christie +Copyright (c) 2011-2015, Tom Christie All rights reserved. Redistribution and use in source and binary forms, with or without -- cgit v1.2.3 From 336faf5a861fad2e4364a68fbf0747bef4457358 Mon Sep 17 00:00:00 2001 From: Rob Terhaar Date: Thu, 1 Jan 2015 21:01:16 -0500 Subject: fix widget style formatting --- docs/tutorial/1-serialization.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs') diff --git a/docs/tutorial/1-serialization.md b/docs/tutorial/1-serialization.md index ff507a2b..60a3d989 100644 --- a/docs/tutorial/1-serialization.md +++ b/docs/tutorial/1-serialization.md @@ -124,7 +124,7 @@ The first part of the serializer class defines the fields that get serialized/de A serializer class is very similar to a Django `Form` class, and includes similar validation flags on the various fields, such as `required`, `max_length` and `default`. -The field flags can also control how the serializer should be displayed in certain circumstances, such as when rendering to HTML. The `style={'type': 'textarea'}` flag above is equivelent to using `widget=widgets.Textarea` on a Django `Form` class. This is particularly useful for controlling how the browsable API should be displayed, as we'll see later in the tutorial. +The field flags can also control how the serializer should be displayed in certain circumstances, such as when rendering to HTML. The `{'base_template': 'textarea.html'}` flag above is equivelent to using `widget=widgets.Textarea` on a Django `Form` class. This is particularly useful for controlling how the browsable API should be displayed, as we'll see later in the tutorial. We can actually also save ourselves some time by using the `ModelSerializer` class, as we'll see later, but for now we'll keep our serializer definition explicit. @@ -206,7 +206,7 @@ One nice property that serializers have is that you can inspect all the fields i SnippetSerializer(): id = IntegerField(label='ID', read_only=True) title = CharField(allow_blank=True, max_length=100, required=False) - code = CharField(style={'type': 'textarea'}) + code = CharField(style={'base_template': 'textarea.html'}) linenos = BooleanField(required=False) language = ChoiceField(choices=[('Clipper', 'FoxPro'), ('Cucumber', 'Gherkin'), ('RobotFramework', 'RobotFramework'), ('abap', 'ABAP'), ('ada', 'Ada')... style = ChoiceField(choices=[('autumn', 'autumn'), ('borland', 'borland'), ('bw', 'bw'), ('colorful', 'colorful')... -- cgit v1.2.3 From 309b5d264166e07510d6cbc54d681268d07957aa Mon Sep 17 00:00:00 2001 From: Craig Blaszczyk Date: Fri, 2 Jan 2015 11:07:35 +0000 Subject: instructions on how to translate REST framework error messages --- docs/topics/internationalisation.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 docs/topics/internationalisation.md (limited to 'docs') diff --git a/docs/topics/internationalisation.md b/docs/topics/internationalisation.md new file mode 100644 index 00000000..01f96891 --- /dev/null +++ b/docs/topics/internationalisation.md @@ -0,0 +1,34 @@ +# Internationalisation +REST framework ships with translatable error messages. You can make these appear in your language enabling [Django's standard translation mechanisms](https://docs.djangoproject.com/en/1.7/topics/i18n/translation) and by translating the messages into your language. + +## How to translate REST Framework errors + + +This guide assumes you are already familiar with how to translate a Django app. If you're not, start by reading [Django's translation docs](https://docs.djangoproject.com/en/1.7/topics/i18n/translation). + + +#### To translate REST framework error messages: + +1. Pick an app where you want the translations to be, for example `myapp` + +2. Add a symlink from that app to the installed `rest_framework` + ``` + ln -s /home/user/.virtualenvs/myproject/lib/python2.7/site-packages/rest_framework/ rest_framework + ``` + + To find out where `rest_framework` is installed, run + + ``` + python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())" + ``` + +3. Run Django's `makemessages` command in the normal way, but add the `--symlink` option. For example, if you want to translate into Brazilian Portuguese you would run + ``` + manage.py makemessages --symlink -l pt_BR + ``` + +4. Translate the `django.po` file which is created as normal. This will be in the folder `myapp/locale/pt_BR/LC_MESSAGES`. + +5. Run `manage.py compilemessages` as normal + +6. Restart your server -- cgit v1.2.3 From 7ad7dd6a4292157ed5bcbaacb60b6ccc93fcf201 Mon Sep 17 00:00:00 2001 From: Craig Blaszczyk Date: Wed, 24 Dec 2014 18:26:17 +0000 Subject: match DRF style guide --- docs/topics/internationalisation.md | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'docs') diff --git a/docs/topics/internationalisation.md b/docs/topics/internationalisation.md index 01f96891..552fdd27 100644 --- a/docs/topics/internationalisation.md +++ b/docs/topics/internationalisation.md @@ -1,10 +1,10 @@ # Internationalisation -REST framework ships with translatable error messages. You can make these appear in your language enabling [Django's standard translation mechanisms](https://docs.djangoproject.com/en/1.7/topics/i18n/translation) and by translating the messages into your language. +REST framework ships with translatable error messages. You can make these appear in your language enabling [Django's standard translation mechanisms][django-translation] and by translating the messages into your language. ## How to translate REST Framework errors -This guide assumes you are already familiar with how to translate a Django app. If you're not, start by reading [Django's translation docs](https://docs.djangoproject.com/en/1.7/topics/i18n/translation). +This guide assumes you are already familiar with how to translate a Django app. If you're not, start by reading [Django's translation docs][django-translation]. #### To translate REST framework error messages: @@ -16,19 +16,28 @@ This guide assumes you are already familiar with how to translate a Django app. ln -s /home/user/.virtualenvs/myproject/lib/python2.7/site-packages/rest_framework/ rest_framework ``` - To find out where `rest_framework` is installed, run + --- + + **Note:** To find out where `rest_framework` is installed, run ``` python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())" ``` -3. Run Django's `makemessages` command in the normal way, but add the `--symlink` option. For example, if you want to translate into Brazilian Portuguese you would run + --- + + + +3. Run Django's `makemessages` command in the normal way, but add the `--symlink` option. For example, if you want to translate into Brazilian Portuguese you would run ``` manage.py makemessages --symlink -l pt_BR ``` -4. Translate the `django.po` file which is created as normal. This will be in the folder `myapp/locale/pt_BR/LC_MESSAGES`. +4. Translate the `django.po` file which is created as normal. This will be in the folder `myapp/locale/pt_BR/LC_MESSAGES`. 5. Run `manage.py compilemessages` as normal 6. Restart your server + + +[django-translation]: https://docs.djangoproject.com/en/1.7/topics/i18n/translation -- cgit v1.2.3 From 2781903a5a0be7f5314de54ff2dbc8ef393eab0a Mon Sep 17 00:00:00 2001 From: Craig Blaszczyk Date: Fri, 26 Dec 2014 12:52:17 +0000 Subject: Add info about how django chooses which language to use --- docs/topics/internationalisation.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'docs') diff --git a/docs/topics/internationalisation.md b/docs/topics/internationalisation.md index 552fdd27..a0aab753 100644 --- a/docs/topics/internationalisation.md +++ b/docs/topics/internationalisation.md @@ -40,4 +40,22 @@ This guide assumes you are already familiar with how to translate a Django app. 6. Restart your server + +## How Django chooses which language to use +REST framework will use the same preferences to select which language to display as Django does. You can find more info in the [django docs on discovering language preferences][django-language-preference]. For reference, these are + +1. First, it looks for the language prefix in the requested URL +2. Failing that, it looks for the `LANGUAGE_SESSION_KEY` key in the current user’s session. +3. Failing that, it looks for a cookie +4. Failing that, it looks at the `Accept-Language` HTTP header. +5. Failing that, it uses the global `LANGUAGE_CODE` setting. + +--- + +**Note:** You'll need to include the `django.middleware.locale.LocaleMiddleware` to enable any of the per-request language preferences. + +--- + + [django-translation]: https://docs.djangoproject.com/en/1.7/topics/i18n/translation +[django-language-preference]: https://docs.djangoproject.com/en/1.7/topics/i18n/translation/#how-django-discovers-language-preference -- cgit v1.2.3 From 0b8a83bd624673cb0a05e01c691729ccee3a8782 Mon Sep 17 00:00:00 2001 From: Craig Blaszczyk Date: Sun, 28 Dec 2014 18:20:41 +0000 Subject: update internationalisation instructions to prevent symlinking; add base .po file --- docs/topics/internationalisation.md | 52 +++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 11 deletions(-) (limited to 'docs') diff --git a/docs/topics/internationalisation.md b/docs/topics/internationalisation.md index a0aab753..6470ee03 100644 --- a/docs/topics/internationalisation.md +++ b/docs/topics/internationalisation.md @@ -9,13 +9,41 @@ This guide assumes you are already familiar with how to translate a Django app. #### To translate REST framework error messages: -1. Pick an app where you want the translations to be, for example `myapp` +1. Make a new folder where you want to store the translated errors. Add this +path to your [`LOCALE_PATHS`][django-locale-paths] setting. + + --- + + **Note:** For the rest of +this document we will assume the path you created was +`/home/www/project/conf/locale/`, and that you have updated your `settings.py` to include the setting: + + ``` + LOCALE_PATHS = ( + '/home/www/project/conf/locale/', + ) + ``` + + --- + +2. Now create a subfolder for the language you want to translate. The folder should be named using [locale +name][django-locale-name] notation. E.g. `de`, `pt_BR`, `es_AR`, etc. -2. Add a symlink from that app to the installed `rest_framework` ``` - ln -s /home/user/.virtualenvs/myproject/lib/python2.7/site-packages/rest_framework/ rest_framework + mkdir /home/www/project/conf/locale/pt_BR/LC_MESSAGES + ``` + +3. Now copy the base translations file from the REST framework source code +into your translations folder + + ``` + cp /home/user/.virtualenvs/myproject/lib/python2.7/site-packages/rest_framework/locale/en_US/LC_MESSAGES/django.po + /home/www/project/conf/locale/pt_BR/LC_MESSAGES ``` + This should create the file + `/home/www/project/conf/locale/pt_BR/LC_MESSAGES/django.po` + --- **Note:** To find out where `rest_framework` is installed, run @@ -27,17 +55,17 @@ This guide assumes you are already familiar with how to translate a Django app. --- +4. Edit `/home/www/project/conf/locale/pt_BR/LC_MESSAGES/django.po` and +translate all the error messages. -3. Run Django's `makemessages` command in the normal way, but add the `--symlink` option. For example, if you want to translate into Brazilian Portuguese you would run - ``` - manage.py makemessages --symlink -l pt_BR - ``` - -4. Translate the `django.po` file which is created as normal. This will be in the folder `myapp/locale/pt_BR/LC_MESSAGES`. +5. Run `manage.py compilemessages -l pt_BR` to make the translations +available for Django to use. You should see a message -5. Run `manage.py compilemessages` as normal + ``` + processing file django.po in /home/www/project/conf/locale/pt_BR/LC_MESSAGES + ``` -6. Restart your server +6. Restart your server. @@ -59,3 +87,5 @@ REST framework will use the same preferences to select which language to display [django-translation]: https://docs.djangoproject.com/en/1.7/topics/i18n/translation [django-language-preference]: https://docs.djangoproject.com/en/1.7/topics/i18n/translation/#how-django-discovers-language-preference +[django-locale-paths]: https://docs.djangoproject.com/en/1.7/ref/settings/#std:setting-LOCALE_PATHS +[django-locale-name]: https://docs.djangoproject.com/en/1.7/topics/i18n/#term-locale-name \ No newline at end of file -- cgit v1.2.3 From 9f169acb62a6223a5add0fee7f6d53108e42f207 Mon Sep 17 00:00:00 2001 From: Craig Blaszczyk Date: Wed, 31 Dec 2014 14:56:23 +0000 Subject: capitalise Django --- docs/topics/internationalisation.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/topics/internationalisation.md b/docs/topics/internationalisation.md index 6470ee03..fac3bdb7 100644 --- a/docs/topics/internationalisation.md +++ b/docs/topics/internationalisation.md @@ -70,7 +70,8 @@ available for Django to use. You should see a message ## How Django chooses which language to use -REST framework will use the same preferences to select which language to display as Django does. You can find more info in the [django docs on discovering language preferences][django-language-preference]. For reference, these are +REST framework will use the same preferences to select which language to +display as Django does. You can find more info in the [Django docs on discovering language preferences][django-language-preference]. For reference, these are 1. First, it looks for the language prefix in the requested URL 2. Failing that, it looks for the `LANGUAGE_SESSION_KEY` key in the current user’s session. -- cgit v1.2.3 From 17665aa52a9cd5599099c19fd8f54540a5d436ce Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 5 Jan 2015 12:26:15 +0000 Subject: Add docs for OAuth, XML, YAML, JSONP packages. Closes #2179. --- docs/api-guide/authentication.md | 47 +++++++++++++++++++++-- docs/api-guide/parsers.md | 51 +++++++++++++++++++++++-- docs/api-guide/renderers.md | 80 +++++++++++++++++++++++++++++++++++++++- docs/index.md | 9 ++--- 4 files changed, 172 insertions(+), 15 deletions(-) (limited to 'docs') diff --git a/docs/api-guide/authentication.md b/docs/api-guide/authentication.md index 2074f1bf..bb731817 100755 --- a/docs/api-guide/authentication.md +++ b/docs/api-guide/authentication.md @@ -293,13 +293,48 @@ The following example will authenticate any incoming request as the user given b The following third party packages are also available. -## Digest Authentication +## Django OAuth Toolkit -HTTP digest authentication is a widely implemented scheme that was intended to replace HTTP basic authentication, and which provides a simple encrypted authentication mechanism. [Juan Riaza][juanriaza] maintains the [djangorestframework-digestauth][djangorestframework-digestauth] package which provides HTTP digest authentication support for REST framework. +The [Django OAuth Toolkit][django-oauth-toolkit] package provides OAuth 2.0 support, and works with Python 2.7 and Python 3.3+. The package is maintained by [Evonove][evonove] and uses the excellent [OAuthLib][oauthlib]. The package is well documented, and well supported and is currently our **recommended package for OAuth 2.0 support**. -## Django OAuth Toolkit +#### Installation & configuration + +Install using `pip`. + + pip install django-oauth-toolkit + +Add the package to your `INSTALLED_APPS` and modify your REST framework settings. -The [Django OAuth Toolkit][django-oauth-toolkit] package provides OAuth 2.0 support, and works with Python 2.7 and Python 3.3+. The package is maintained by [Evonove][evonove] and uses the excellent [OAuthLib][oauthlib]. The package is well documented, and comes as a recommended alternative for OAuth 2.0 support. + INSTALLED_APPS = ( + ... + 'oauth2_provider', + ) + + REST_FRAMEWORK = { + 'DEFAULT_AUTHENTICATION_CLASSES': ( + 'oauth2_provider.ext.rest_framework.OAuth2Authentication', + ) + } + +For more details see the [Django REST framework - Getting started][django-oauth-toolkit-getting-started] documentation. + +## Django REST framework OAuth + +The [Django REST framework OAuth][django-rest-framework-oauth] package provides both OAuth1 and OAuth2 support for REST framework. + +This package was previously included directly in REST framework but is now supported and maintained as a third party package. + +#### Installation & configuration + +Install the package using `pip`. + + pip install djangorestframework-oauth + +For details on configuration and usage see the Django REST framework OAuth documentation for [authentication][django-rest-framework-oauth-authentication] and [permissions][django-rest-framework-oauth-permissions]. + +## Digest Authentication + +HTTP digest authentication is a widely implemented scheme that was intended to replace HTTP basic authentication, and which provides a simple encrypted authentication mechanism. [Juan Riaza][juanriaza] maintains the [djangorestframework-digestauth][djangorestframework-digestauth] package which provides HTTP digest authentication support for REST framework. ## Django OAuth2 Consumer @@ -332,6 +367,10 @@ HTTP Signature (currently a [IETF draft][http-signature-ietf-draft]) provides a [mod_wsgi_official]: http://code.google.com/p/modwsgi/wiki/ConfigurationDirectives#WSGIPassAuthorization [custom-user-model]: https://docs.djangoproject.com/en/dev/topics/auth/customizing/#specifying-a-custom-user-model [south-dependencies]: http://south.readthedocs.org/en/latest/dependencies.html +[django-oauth-toolkit-getting-started]: https://django-oauth-toolkit.readthedocs.org/en/latest/rest-framework/getting_started.html +[django-rest-framework-oauth]: http://jpadilla.github.io/django-rest-framework-oauth/ +[django-rest-framework-oauth-authentication]: http://jpadilla.github.io/django-rest-framework-oauth/authentication/ +[django-rest-framework-oauth-permissions]: http://jpadilla.github.io/django-rest-framework-oauth/permissions/ [juanriaza]: https://github.com/juanriaza [djangorestframework-digestauth]: https://github.com/juanriaza/django-rest-framework-digestauth [oauth-1.0a]: http://oauth.net/core/1.0a diff --git a/docs/api-guide/parsers.md b/docs/api-guide/parsers.md index 9323d382..b68b33be 100644 --- a/docs/api-guide/parsers.md +++ b/docs/api-guide/parsers.md @@ -26,7 +26,7 @@ As an example, if you are sending `json` encoded data using jQuery with the [.aj ## Setting the parsers -The default set of parsers may be set globally, using the `DEFAULT_PARSER_CLASSES` setting. For example, the following settings would allow requests with `JSON` content. +The default set of parsers may be set globally, using the `DEFAULT_PARSER_CLASSES` setting. For example, the following settings would allow only requests with `JSON` content, instead of the default of JSON or form data. REST_FRAMEWORK = { 'DEFAULT_PARSER_CLASSES': ( @@ -37,8 +37,8 @@ The default set of parsers may be set globally, using the `DEFAULT_PARSER_CLASSE You can also set the parsers used for an individual view, or viewset, using the `APIView` class based views. - from rest_framework.parsers import JSONParser - from rest_framework.response import Response + from rest_framework.parsers import JSONParser + from rest_framework.response import Response from rest_framework.views import APIView class ExampleView(APIView): @@ -162,6 +162,48 @@ The following is an example plaintext parser that will populate the `request.dat The following third party packages are also available. +## YAML + +[REST framework YAML][rest-framework-yaml] provides [YAML][yaml] parsing and rendering support. It was previously included directly in the REST framework package, and is now instead supported as a third-party package. + +#### Installation & configuration + +Install using pip. + + $ pip install djangorestframework-yaml + +Modify your REST framework settings. + + REST_FRAMEWORK = { + 'DEFAULT_PARSER_CLASSES': ( + 'rest_framework_yaml.parsers.YAMLParser', + ), + 'DEFAULT_RENDERER_CLASSES': ( + 'rest_framework_yaml.renderers.YAMLRenderer', + ), + } + +## XML + +[REST Framework XML][rest-framework-xml] provides a simple informal XML format. It was previously included directly in the REST framework package, and is now instead supported as a third-party package. + +#### Installation & configuration + +Install using pip. + + $ pip install djangorestframework-xml + +Modify your REST framework settings. + + REST_FRAMEWORK = { + 'DEFAULT_PARSER_CLASSES': ( + 'rest_framework_xml.parsers.XMLParser', + ), + 'DEFAULT_RENDERER_CLASSES': ( + 'rest_framework_xml.renderers.XMLRenderer', + ), + } + ## MessagePack [MessagePack][messagepack] is a fast, efficient binary serialization format. [Juan Riaza][juanriaza] maintains the [djangorestframework-msgpack][djangorestframework-msgpack] package which provides MessagePack renderer and parser support for REST framework. @@ -173,6 +215,9 @@ The following third party packages are also available. [jquery-ajax]: http://api.jquery.com/jQuery.ajax/ [cite]: https://groups.google.com/d/topic/django-developers/dxI4qVzrBY4/discussion [upload-handlers]: https://docs.djangoproject.com/en/dev/topics/http/file-uploads/#upload-handlers +[rest-framework-yaml]: http://jpadilla.github.io/django-rest-framework-yaml/ +[rest-framework-xml]: http://jpadilla.github.io/django-rest-framework-xml/ +[yaml]: http://www.yaml.org/ [messagepack]: https://github.com/juanriaza/django-rest-framework-msgpack [juanriaza]: https://github.com/juanriaza [vbabiy]: https://github.com/vbabiy diff --git a/docs/api-guide/renderers.md b/docs/api-guide/renderers.md index 69460dbc..83ded849 100644 --- a/docs/api-guide/renderers.md +++ b/docs/api-guide/renderers.md @@ -342,13 +342,81 @@ Templates will render with a `RequestContext` which includes the `status_code` a The following third party packages are also available. +## YAML + +[REST framework YAML][rest-framework-yaml] provides [YAML][yaml] parsing and rendering support. It was previously included directly in the REST framework package, and is now instead supported as a third-party package. + +#### Installation & configuration + +Install using pip. + + $ pip install djangorestframework-yaml + +Modify your REST framework settings. + + REST_FRAMEWORK = { + 'DEFAULT_PARSER_CLASSES': ( + 'rest_framework_yaml.parsers.YAMLParser', + ), + 'DEFAULT_RENDERER_CLASSES': ( + 'rest_framework_yaml.renderers.YAMLRenderer', + ), + } + +## XML + +[REST Framework XML][rest-framework-xml] provides a simple informal XML format. It was previously included directly in the REST framework package, and is now instead supported as a third-party package. + +#### Installation & configuration + +Install using pip. + + $ pip install djangorestframework-xml + +Modify your REST framework settings. + + REST_FRAMEWORK = { + 'DEFAULT_PARSER_CLASSES': ( + 'rest_framework_xml.parsers.XMLParser', + ), + 'DEFAULT_RENDERER_CLASSES': ( + 'rest_framework_xml.renderers.XMLRenderer', + ), + } + +## JSONP + +[REST framework JSONP][rest-framework-jsonp] provides JSONP rendering support. It was previously included directly in the REST framework package, and is now instead supported as a third-party package. + +--- + +**Warning**: If you require cross-domain AJAX requests, you should generally be using the more modern approach of [CORS][cors] as an alternative to `JSONP`. See the [CORS documentation][cors-docs] for more details. + +The `jsonp` approach is essentially a browser hack, and is [only appropriate for globally readable API endpoints][jsonp-security], where `GET` requests are unauthenticated and do not require any user permissions. + +--- + +#### Installation & configuration + +Install using pip. + + $ pip install djangorestframework-jsonp + +Modify your REST framework settings. + + REST_FRAMEWORK = { + 'DEFAULT_RENDERER_CLASSES': ( + 'rest_framework_yaml.renderers.JSONPRenderer', + ), + } + ## MessagePack [MessagePack][messagepack] is a fast, efficient binary serialization format. [Juan Riaza][juanriaza] maintains the [djangorestframework-msgpack][djangorestframework-msgpack] package which provides MessagePack renderer and parser support for REST framework. ## CSV -Comma-separated values are a plain-text tabular data format, that can be easily imported into spreadsheet applications. [Mjumbe Poe][mjumbewu] maintains the [djangorestframework-csv][djangorestframework-csv] package which provides CSV renderer support for REST framework. +Comma-separated values are a plain-text tabular data format, that can be easily imported into spreadsheet applications. [Mjumbe Poe][mjumbewu] maintains the [djangorestframework-csv][djangorestframework-csv] package which provides CSV renderer support for REST framework. ## UltraJSON @@ -358,7 +426,6 @@ Comma-separated values are a plain-text tabular data format, that can be easily [djangorestframework-camel-case] provides camel case JSON renderers and parsers for REST framework. This allows serializers to use Python-style underscored field names, but be exposed in the API as Javascript-style camel case field names. It is maintained by [Vitaly Babiy][vbabiy]. - ## Pandas (CSV, Excel, PNG) [Django REST Pandas] provides a serializer and renderers that support additional data processing and output via the [Pandas] DataFrame API. Django REST Pandas includes renderers for Pandas-style CSV files, Excel workbooks (both `.xls` and `.xlsx`), and a number of [other formats]. It is maintained by [S. Andrew Sheppard][sheppard] as part of the [wq Project][wq]. @@ -373,10 +440,19 @@ Comma-separated values are a plain-text tabular data format, that can be easily [application/vnd.github+json]: http://developer.github.com/v3/media/ [application/vnd.collection+json]: http://www.amundsen.com/media-types/collection/ [django-error-views]: https://docs.djangoproject.com/en/dev/topics/http/views/#customizing-error-views +[rest-framework-jsonp]: http://jpadilla.github.io/django-rest-framework-jsonp/ +[cors]: http://www.w3.org/TR/cors/ +[cors-docs]: http://www.django-rest-framework.org/topics/ajax-csrf-cors/ +[jsonp-security]: http://stackoverflow.com/questions/613962/is-jsonp-safe-to-use +[rest-framework-yaml]: http://jpadilla.github.io/django-rest-framework-yaml/ +[rest-framework-xml]: http://jpadilla.github.io/django-rest-framework-xml/ [messagepack]: http://msgpack.org/ [juanriaza]: https://github.com/juanriaza [mjumbewu]: https://github.com/mjumbewu [vbabiy]: https://github.com/vbabiy +[rest-framework-yaml]: http://jpadilla.github.io/django-rest-framework-yaml/ +[rest-framework-xml]: http://jpadilla.github.io/django-rest-framework-xml/ +[yaml]: http://www.yaml.org/ [djangorestframework-msgpack]: https://github.com/juanriaza/django-rest-framework-msgpack [djangorestframework-csv]: https://github.com/mjumbewu/django-rest-framework-csv [ultrajson]: https://github.com/esnme/ultrajson diff --git a/docs/index.md b/docs/index.md index 7ccec12f..544204c6 100644 --- a/docs/index.md +++ b/docs/index.md @@ -28,13 +28,12 @@ For more details see the [3.0 release notes][3.0-announcement]. Django REST Framework

- Django REST framework is a powerful and flexible toolkit that makes it easy to build Web APIs. Some reasons you might want to use REST framework: * The [Web browsable API][sandbox] is a huge usability win for your developers. -* [Authentication policies][authentication] including optional packages for [OAuth1a][oauth1-section] and [OAuth2][oauth2-section]. +* [Authentication policies][authentication] including packages for [OAuth1a][oauth1-section] and [OAuth2][oauth2-section]. * [Serialization][serializers] that supports both [ORM][modelserializer-section] and [non-ORM][serializer-section] data sources. * Customizable all the way down - just use [regular function-based views][functionview-section] if you don't need the [more][generic-views] [powerful][viewsets] [features][routers]. * [Extensive documentation][index], and [great community support][group]. @@ -57,7 +56,6 @@ The following packages are optional: * [Markdown][markdown] (2.1.0+) - Markdown support for the browsable API. * [django-filter][django-filter] (0.5.4+) - Filtering support. -* [django-restframework-oauth][django-restframework-oauth] package for OAuth 1.0a and 2.0 support. * [django-guardian][django-guardian] (1.1.1+) - Object level permissions support. ## Installation @@ -260,13 +258,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [eventbrite]: https://www.eventbrite.co.uk/about/ [markdown]: http://pypi.python.org/pypi/Markdown/ [django-filter]: http://pypi.python.org/pypi/django-filter -[django-restframework-oauth]: https://github.com/jlafon/django-rest-framework-oauth [django-guardian]: https://github.com/lukaszb/django-guardian [0.4]: https://github.com/tomchristie/django-rest-framework/tree/0.4.X [image]: img/quickstart.png [index]: . -[oauth1-section]: api-guide/authentication#oauthauthentication -[oauth2-section]: api-guide/authentication#oauth2authentication +[oauth1-section]: api-guide/authentication/#django-rest-framework-oauth +[oauth2-section]: api-guide/authentication/#django-oauth-toolkit [serializer-section]: api-guide/serializers#serializers [modelserializer-section]: api-guide/serializers#modelserializer [functionview-section]: api-guide/views#function-based-views -- cgit v1.2.3 From b6ca7248ebcf95a95e1911aa0b130f653b8bf690 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 5 Jan 2015 14:32:12 +0000 Subject: required=False allows omission of value for output. Closes #2342 --- docs/api-guide/fields.md | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docs') diff --git a/docs/api-guide/fields.md b/docs/api-guide/fields.md index 946e355d..b3d274dd 100644 --- a/docs/api-guide/fields.md +++ b/docs/api-guide/fields.md @@ -41,6 +41,8 @@ Defaults to `False` Normally an error will be raised if a field is not supplied during deserialization. Set to false if this field is not required to be present during deserialization. +Setting this to `False` also allows the object attribute or dictionary key to be omitted from output when serializing the instance. If the key is not present it will simply not be included in the output representation. + Defaults to `True`. ### `allow_null` -- cgit v1.2.3 From d3b2302588f333b22d5e4aa2be6eca0e944e9494 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 5 Jan 2015 16:31:52 +0000 Subject: Minor docs update. Refs #2375. --- docs/topics/3.0-announcement.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs') diff --git a/docs/topics/3.0-announcement.md b/docs/topics/3.0-announcement.md index 68d24782..5dbc5600 100644 --- a/docs/topics/3.0-announcement.md +++ b/docs/topics/3.0-announcement.md @@ -87,12 +87,12 @@ The resulting API changes are further detailed below. #### The `.create()` and `.update()` methods. -The `.restore_object()` method is now replaced with two separate methods, `.create()` and `.update()`. - -These methods also replace the optional `.save_object()` method, which no longer exists. +The `.restore_object()` method is now removed, and we instead have two separate methods, `.create()` and `.update()`. These methods work slightly different to the previous `.restore_object()`. When using the `.create()` and `.update()` methods you should both create *and save* the object instance. This is in contrast to the previous `.restore_object()` behavior that would instantiate the object but not save it. +These methods also replace the optional `.save_object()` method, which no longer exists. + The following example from the tutorial previously used `restore_object()` to handle both creating and updating object instances. def restore_object(self, attrs, instance=None): -- cgit v1.2.3 From 271b638df10c0cf498cbc69847f388e978c4da78 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Tue, 6 Jan 2015 11:21:58 +0000 Subject: Update exception docs. Closes #2378. --- docs/api-guide/exceptions.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/api-guide/exceptions.md b/docs/api-guide/exceptions.md index 467ad970..993134f7 100644 --- a/docs/api-guide/exceptions.md +++ b/docs/api-guide/exceptions.md @@ -18,7 +18,7 @@ The handled exceptions are: In each case, REST framework will return a response with an appropriate status code and content-type. The body of the response will include any additional details regarding the nature of the error. -By default all error responses will include a key `detail` in the body of the response, but other keys may also be included. +Most error responses will include a key `detail` in the body of the response. For example, the following request: @@ -33,6 +33,16 @@ Might receive an error response indicating that the `DELETE` method is not allow {"detail": "Method 'DELETE' not allowed."} +Validation errors are handled slightly differently, and will include the field names as the keys in the response. If the validation error was not specific to a particular field then it will use the "non_field_errors" key, or whatever string value has been set for the `NON_FIELD_ERRORS_KEY` setting. + +Any example validation error might look like this: + + HTTP/1.1 400 Bad Request + Content-Type: application/json + Content-Length: 94 + + {"amount": ["A valid integer is required."], "description": ["This field may not be blank."]} + ## Custom exception handling You can implement custom exception handling by creating a handler function that converts exceptions raised in your API views into response objects. This allows you to control the style of error responses used by your API. -- cgit v1.2.3 From fe92a2cfee9e3a20e913500802d98a15e8b70780 Mon Sep 17 00:00:00 2001 From: JocelynDelalande Date: Wed, 7 Jan 2015 10:42:11 +0100 Subject: fixed doc : DEFAULT_AUTHENTICATION_CLASSES -> DEFAULT_AUTHENTICATION + It is consistent with docs about DEFAULT_PERMISSION_CLASSES--- docs/api-guide/authentication.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs') diff --git a/docs/api-guide/authentication.md b/docs/api-guide/authentication.md index b04858e3..1222dbf0 100755 --- a/docs/api-guide/authentication.md +++ b/docs/api-guide/authentication.md @@ -34,7 +34,7 @@ The value of `request.user` and `request.auth` for unauthenticated requests can ## Setting the authentication scheme -The default authentication schemes may be set globally, using the `DEFAULT_AUTHENTICATION` setting. For example. +The default authentication schemes may be set globally, using the `DEFAULT_AUTHENTICATION_CLASSES` setting. For example. REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( @@ -282,7 +282,7 @@ This authentication class depends on the optional [django-oauth2-provider][djang 'provider.oauth2', ) -Then add `OAuth2Authentication` to your global `DEFAULT_AUTHENTICATION` setting: +Then add `OAuth2Authentication` to your global `DEFAULT_AUTHENTICATION_CLASSES` setting: 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework.authentication.OAuth2Authentication', -- cgit v1.2.3 From 7913947757b0e6bd1b8828db81933c32c498e20a Mon Sep 17 00:00:00 2001 From: Craig Blaszczyk Date: Wed, 7 Jan 2015 11:13:03 +0000 Subject: add config and documentation about uploading/downloading translations from Transifex --- docs/topics/internationalisation.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'docs') diff --git a/docs/topics/internationalisation.md b/docs/topics/internationalisation.md index fac3bdb7..2a476c86 100644 --- a/docs/topics/internationalisation.md +++ b/docs/topics/internationalisation.md @@ -3,11 +3,13 @@ REST framework ships with translatable error messages. You can make these appea ## How to translate REST Framework errors +REST framework translations are managed online using [Transifex.com][transifex]. To get started, checkout the guide in the [CONTRIBUTING.md guide][contributing]. -This guide assumes you are already familiar with how to translate a Django app. If you're not, start by reading [Django's translation docs][django-translation]. +Sometimes you may want to use REST Framework in a language which has not been translated yet on Transifex. If that is the case then you should translate the error messages locally. +#### How to translate REST Framework error messages locally: -#### To translate REST framework error messages: +This guide assumes you are already familiar with how to translate a Django app. If you're not, start by reading [Django's translation docs][django-translation]. 1. Make a new folder where you want to store the translated errors. Add this path to your [`LOCALE_PATHS`][django-locale-paths] setting. @@ -89,4 +91,5 @@ display as Django does. You can find more info in the [Django docs on discoveri [django-translation]: https://docs.djangoproject.com/en/1.7/topics/i18n/translation [django-language-preference]: https://docs.djangoproject.com/en/1.7/topics/i18n/translation/#how-django-discovers-language-preference [django-locale-paths]: https://docs.djangoproject.com/en/1.7/ref/settings/#std:setting-LOCALE_PATHS -[django-locale-name]: https://docs.djangoproject.com/en/1.7/topics/i18n/#term-locale-name \ No newline at end of file +[django-locale-name]: https://docs.djangoproject.com/en/1.7/topics/i18n/#term-locale-name +[contributing]: ../../CONTRIBUTING.md -- cgit v1.2.3 From 42f1932b520a90ae6f8e11246a0992e5f8983bd7 Mon Sep 17 00:00:00 2001 From: Xavier Ordoquy Date: Wed, 7 Jan 2015 19:10:22 +0100 Subject: Release notes for 3.0.3 --- docs/topics/release-notes.md | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'docs') diff --git a/docs/topics/release-notes.md b/docs/topics/release-notes.md index b9216e36..18a47b71 100644 --- a/docs/topics/release-notes.md +++ b/docs/topics/release-notes.md @@ -40,6 +40,26 @@ You can determine your currently installed version using `pip freeze`: ## 3.0.x series + +### 3.0.3 + +**Date**: [8th January 2015][3.0.3-milestone]. + +* Fix `MinValueValidator` on `models.DateField`. ([#2369][gh2369]) +* Fix serializer missing context when pagination is used. ([#2355][gh2355]) +* Namespaced router URLs are now supported by the `DefaultRouter`. ([#2351][gh2351]) +* `required=False` allows omission of value for output. ([#2342][gh2342]) +* Use textarea input for `models.TextField`. ([#2340][gh2340]) +* Use custom `ListSerializer` for pagination if required. ([#2331][gh2331], [#2327][gh2327]) +* Better behavior with null and '' for blank HTML fields. ([#2330][gh2330]) +* Ensure fields in `exclude` are model fields. ([#2319][gh2319]) +* Fix `IntegerField` and `max_length` argument incompatibility. ([#2317][gh2317]) +* Fix the YAML encoder for 3.0 serializers. ([#2315][gh2315], [#2283][gh2283]) +* Fix the behavior of empty HTML fields. ([#2311][gh2311], [#1101][gh1101]) +* Fix Metaclass attribute depth ignoring fields attribute. ([#2287][gh2287]) +* Fix `format_suffix_patterns` to work with Django's `i18n_patterns`. ([#2278][gh2278]) +* Ability to customize router URLs for custom actions, using `url_path`. ([#2010][gh2010]) + ### 3.0.2 **Date**: [17th December 2014][3.0.2-milestone]. @@ -729,3 +749,21 @@ For older release notes, [please see the GitHub repo](old-release-notes). [gh2290]: https://github.com/tomchristie/django-rest-framework/issues/2290 [gh2291]: https://github.com/tomchristie/django-rest-framework/issues/2291 [gh2294]: https://github.com/tomchristie/django-rest-framework/issues/2294 + +[gh1101]: https://github.com/tomchristie/django-rest-framework/issues/1101 +[gh2010]: https://github.com/tomchristie/django-rest-framework/issues/2010 +[gh2278]: https://github.com/tomchristie/django-rest-framework/issues/2278 +[gh2283]: https://github.com/tomchristie/django-rest-framework/issues/2283 +[gh2287]: https://github.com/tomchristie/django-rest-framework/issues/2287 +[gh2311]: https://github.com/tomchristie/django-rest-framework/issues/2311 +[gh2315]: https://github.com/tomchristie/django-rest-framework/issues/2315 +[gh2317]: https://github.com/tomchristie/django-rest-framework/issues/2317 +[gh2319]: https://github.com/tomchristie/django-rest-framework/issues/2319 +[gh2327]: https://github.com/tomchristie/django-rest-framework/issues/2327 +[gh2330]: https://github.com/tomchristie/django-rest-framework/issues/2330 +[gh2331]: https://github.com/tomchristie/django-rest-framework/issues/2331 +[gh2340]: https://github.com/tomchristie/django-rest-framework/issues/2340 +[gh2342]: https://github.com/tomchristie/django-rest-framework/issues/2342 +[gh2351]: https://github.com/tomchristie/django-rest-framework/issues/2351 +[gh2355]: https://github.com/tomchristie/django-rest-framework/issues/2355 +[gh2369]: https://github.com/tomchristie/django-rest-framework/issues/2369 -- cgit v1.2.3 From 1102e22cb407b9069ce3301bd578ba45a775a89e Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 7 Jan 2015 21:02:42 +0000 Subject: Update project-management.md --- docs/topics/project-management.md | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'docs') diff --git a/docs/topics/project-management.md b/docs/topics/project-management.md index f581cabd..037b7182 100644 --- a/docs/topics/project-management.md +++ b/docs/topics/project-management.md @@ -58,6 +58,8 @@ The following template should be used for the description of the issue, and serv #### New members. If you wish to be considered for this or a future date, please comment against this or subsequent issues. + + To modify this process for future releases make a pull request to the [project management](http://www.django-rest-framework.org/topics/project-management/) documentation. #### Responsibilities of team members @@ -107,6 +109,8 @@ The following template should be used for the description of the issue, and serv - [ ] Make a release announcement on the [discussion group](https://groups.google.com/forum/?fromgroups#!forum/django-rest-framework). - [ ] Make a release announcement on twitter. - [ ] Close the milestone on GitHub. + + To modify this process for future releases make a pull request to the [project management](http://www.django-rest-framework.org/topics/project-management/) documentation. When pushing the release to PyPI ensure that your environment has been installed from our development `requirement.txt`, so that documentation and PyPI installs are consistently being built against a pinned set of packages. -- cgit v1.2.3 From 18cefad3abfa6e6a7bbd278e8d54eef66a1d1e53 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 7 Jan 2015 21:03:50 +0000 Subject: Update project-management.md --- docs/topics/project-management.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/topics/project-management.md b/docs/topics/project-management.md index 037b7182..bcc0330e 100644 --- a/docs/topics/project-management.md +++ b/docs/topics/project-management.md @@ -59,7 +59,7 @@ The following template should be used for the description of the issue, and serv If you wish to be considered for this or a future date, please comment against this or subsequent issues. - To modify this process for future releases make a pull request to the [project management](http://www.django-rest-framework.org/topics/project-management/) documentation. + To modify this process for future maintenance cycles make a pull request to the [project management](http://www.django-rest-framework.org/topics/project-management/) documentation. #### Responsibilities of team members -- cgit v1.2.3 From e61ef3d39f301bc62323b47af5080877e273c395 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 8 Jan 2015 11:07:47 +0000 Subject: Minor docs updates --- docs/api-guide/filtering.md | 1 + docs/topics/project-management.md | 1 + 2 files changed, 2 insertions(+) (limited to 'docs') diff --git a/docs/api-guide/filtering.md b/docs/api-guide/filtering.md index 83977048..3eb1538f 100644 --- a/docs/api-guide/filtering.md +++ b/docs/api-guide/filtering.md @@ -316,6 +316,7 @@ Typically you'd instead control this by setting `order_by` on the initial querys queryset = User.objects.all() serializer_class = UserSerializer filter_backends = (filters.OrderingFilter,) + ordering_fields = ('username', 'email') ordering = ('username',) The `ordering` attribute may be either a string or a list/tuple of strings. diff --git a/docs/topics/project-management.md b/docs/topics/project-management.md index f581cabd..f052aa83 100644 --- a/docs/topics/project-management.md +++ b/docs/topics/project-management.md @@ -126,6 +126,7 @@ The following issues still need to be addressed: * Ensure `@jamie` has back-up access to the `django-rest-framework.org` domain setup and admin. * Document ownership of the [live example][sandbox] API. * Document ownership of the [mailing list][mailing-list] and IRC channel. +* Document ownership and management of the security mailing list. [bus-factor]: http://en.wikipedia.org/wiki/Bus_factor [un-triaged]: https://github.com/tomchristie/django-rest-framework/issues?q=is%3Aopen+no%3Alabel -- cgit v1.2.3 From f0ad0a88c49f1fef473ef1fbf965bcaa974ee062 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 8 Jan 2015 12:31:51 +0000 Subject: Link to Roy Fielding versioning interview. --- docs/api-guide/versioning.md | 3 +++ 1 file changed, 3 insertions(+) (limited to 'docs') diff --git a/docs/api-guide/versioning.md b/docs/api-guide/versioning.md index 92380cc0..7463f190 100644 --- a/docs/api-guide/versioning.md +++ b/docs/api-guide/versioning.md @@ -10,6 +10,8 @@ API versioning allows you to alter behavior between different clients. REST fram Versioning is determined by the incoming client request, and may either be based on the request URL, or based on the request headers. +There are a number of valid approaches to approaching versioning. [Non-versioned systems can also be appropriate][roy-fielding-on-versioning], particularly if you're engineering for very long-term systems with multiple clients outside of your control. + ## Versioning with REST framework When API versioning is enabled, the `request.version` attribute will contain a string that corresponds to the version requested in the incoming client request. @@ -195,6 +197,7 @@ The following example uses a custom `X-API-Version` header to determine the requ If your versioning scheme is based on the request URL, you will also want to alter how versioned URLs are determined. In order to do so you should override the `.reverse()` method on the class. See the source code for examples. [cite]: http://www.slideshare.net/evolve_conference/201308-fielding-evolve/31 +[roy-fielding-on-versioning]: http://www.infoq.com/articles/roy-fielding-on-versioning [klabnik-guidelines]: http://blog.steveklabnik.com/posts/2011-07-03-nobody-understands-rest-or-http#i_want_my_api_to_be_versioned [heroku-guidelines]: https://github.com/interagent/http-api-design#version-with-accepts-header [json-parameters]: http://tools.ietf.org/html/rfc4627#section-6 -- cgit v1.2.3 From f529f83d3c96ca1957d7a8bfc74bd33151cc8d86 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 8 Jan 2015 14:38:23 +0000 Subject: Minimum Django 1.5 version issue 1.5.6 --- docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/index.md b/docs/index.md index 55129df1..a621e3ec 100644 --- a/docs/index.md +++ b/docs/index.md @@ -51,7 +51,7 @@ Some reasons you might want to use REST framework: REST framework requires the following: * Python (2.6.5+, 2.7, 3.2, 3.3, 3.4) -* Django (1.4.11+, 1.5.5+, 1.6, 1.7) +* Django (1.4.11+, 1.5.6+, 1.6, 1.7) The following packages are optional: -- cgit v1.2.3 From 42c913334b0b4cd731011a07a49ff08aa03d7768 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 8 Jan 2015 14:51:08 +0000 Subject: Minimum 1.6.x version is 1.6.3 --- docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/index.md b/docs/index.md index a621e3ec..d40f8972 100644 --- a/docs/index.md +++ b/docs/index.md @@ -51,7 +51,7 @@ Some reasons you might want to use REST framework: REST framework requires the following: * Python (2.6.5+, 2.7, 3.2, 3.3, 3.4) -* Django (1.4.11+, 1.5.6+, 1.6, 1.7) +* Django (1.4.11+, 1.5.6+, 1.6.3+, 1.7) The following packages are optional: -- cgit v1.2.3 From ef16c546d77d36bbddacf9b66626f7eaf9f4ff17 Mon Sep 17 00:00:00 2001 From: Xavier Ordoquy Date: Thu, 8 Jan 2015 23:29:51 +0100 Subject: Update the release note with latest fixes. Add the link to the 3.0.3 milestone. --- docs/topics/release-notes.md | 3 +++ 1 file changed, 3 insertions(+) (limited to 'docs') diff --git a/docs/topics/release-notes.md b/docs/topics/release-notes.md index 18a47b71..c49dd62c 100644 --- a/docs/topics/release-notes.md +++ b/docs/topics/release-notes.md @@ -59,6 +59,7 @@ You can determine your currently installed version using `pip freeze`: * Fix Metaclass attribute depth ignoring fields attribute. ([#2287][gh2287]) * Fix `format_suffix_patterns` to work with Django's `i18n_patterns`. ([#2278][gh2278]) * Ability to customize router URLs for custom actions, using `url_path`. ([#2010][gh2010]) +* Don't install Django REST Framework as egg. ([#2386][gh2386]) ### 3.0.2 @@ -700,6 +701,7 @@ For older release notes, [please see the GitHub repo](old-release-notes). [3.0.1-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.0.1+Release%22 [3.0.2-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.0.2+Release%22 +[3.0.3-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.0.3+Release%22 [gh2013]: https://github.com/tomchristie/django-rest-framework/issues/2013 @@ -767,3 +769,4 @@ For older release notes, [please see the GitHub repo](old-release-notes). [gh2351]: https://github.com/tomchristie/django-rest-framework/issues/2351 [gh2355]: https://github.com/tomchristie/django-rest-framework/issues/2355 [gh2369]: https://github.com/tomchristie/django-rest-framework/issues/2369 +[gh2386]: https://github.com/tomchristie/django-rest-framework/issues/2386 -- cgit v1.2.3 From 8ccf5bcc0bb3455c0d71a0e0d845ef54489bb28e Mon Sep 17 00:00:00 2001 From: Travis Swientek Date: Fri, 9 Jan 2015 11:36:21 -0800 Subject: Tweaked a few issues in the tutorial documentation. --- docs/tutorial/1-serialization.md | 2 +- docs/tutorial/3-class-based-views.md | 2 +- docs/tutorial/4-authentication-and-permissions.md | 2 +- docs/tutorial/5-relationships-and-hyperlinked-apis.md | 2 ++ 4 files changed, 5 insertions(+), 3 deletions(-) (limited to 'docs') diff --git a/docs/tutorial/1-serialization.md b/docs/tutorial/1-serialization.md index 60a3d989..41ff4d07 100644 --- a/docs/tutorial/1-serialization.md +++ b/docs/tutorial/1-serialization.md @@ -191,7 +191,7 @@ Our `SnippetSerializer` class is replicating a lot of information that's also co In the same way that Django provides both `Form` classes and `ModelForm` classes, REST framework includes both `Serializer` classes, and `ModelSerializer` classes. Let's look at refactoring our serializer using the `ModelSerializer` class. -Open the file `snippets/serializers.py` again, and edit the `SnippetSerializer` class. +Open the file `snippets/serializers.py` again, and replace the `SnippetSerializer` class with the following. class SnippetSerializer(serializers.ModelSerializer): class Meta: diff --git a/docs/tutorial/3-class-based-views.md b/docs/tutorial/3-class-based-views.md index 0a9ea3f1..abf82e49 100644 --- a/docs/tutorial/3-class-based-views.md +++ b/docs/tutorial/3-class-based-views.md @@ -64,7 +64,7 @@ That's looking good. Again, it's still pretty similar to the function based vie We'll also need to refactor our `urls.py` slightly now we're using class based views. - from django.conf.urls import patterns, url + from django.conf.urls import url from rest_framework.urlpatterns import format_suffix_patterns from snippets import views diff --git a/docs/tutorial/4-authentication-and-permissions.md b/docs/tutorial/4-authentication-and-permissions.md index 592c77e8..887d1e56 100644 --- a/docs/tutorial/4-authentication-and-permissions.md +++ b/docs/tutorial/4-authentication-and-permissions.md @@ -177,7 +177,7 @@ In the snippets app, create a new file, `permissions.py` # Write permissions are only allowed to the owner of the snippet. return obj.owner == request.user -Now we can add that custom permission to our snippet instance endpoint, by editing the `permission_classes` property on the `SnippetDetail` class: +Now we can add that custom permission to our snippet instance endpoint, by editing the `permission_classes` property on the `SnippetDetail` view class: permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly,) diff --git a/docs/tutorial/5-relationships-and-hyperlinked-apis.md b/docs/tutorial/5-relationships-and-hyperlinked-apis.md index c21efd7f..2841f03e 100644 --- a/docs/tutorial/5-relationships-and-hyperlinked-apis.md +++ b/docs/tutorial/5-relationships-and-hyperlinked-apis.md @@ -106,6 +106,8 @@ If we're going to have a hyperlinked API, we need to make sure we name our URL p After adding all those names into our URLconf, our final `snippets/urls.py` file should look something like this: + from django.conf.urls import url, include + # API endpoints urlpatterns = format_suffix_patterns([ url(r'^$', views.api_root), -- cgit v1.2.3 From 7f9a62a5bf6a86c4d0a96e5f00d7e96b22d3337f Mon Sep 17 00:00:00 2001 From: Philip Neustrom Date: Tue, 13 Jan 2015 15:19:52 +0800 Subject: Fix link to `django-rest-framework-filters` (formerly `django-rest-framework-chain`) --- docs/api-guide/filtering.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs') diff --git a/docs/api-guide/filtering.md b/docs/api-guide/filtering.md index 07420d84..2b6d5449 100644 --- a/docs/api-guide/filtering.md +++ b/docs/api-guide/filtering.md @@ -388,9 +388,9 @@ We could achieve the same behavior by overriding `get_queryset()` on the views, The following third party packages provide additional filter implementations. -## Django REST framework chain +## Django REST framework filters package -The [django-rest-framework-chain package][django-rest-framework-chain] works together with the `DjangoFilterBackend` class, and allows you to easily create filters across relationships, or create multiple filter lookup types for a given field. +The [django-rest-framework-filters package][django-rest-framework-filters] works together with the `DjangoFilterBackend` class, and allows you to easily create filters across relationships, or create multiple filter lookup types for a given field. [cite]: https://docs.djangoproject.com/en/dev/topics/db/queries/#retrieving-specific-objects-with-filters [django-filter]: https://github.com/alex/django-filter @@ -400,4 +400,4 @@ The [django-rest-framework-chain package][django-rest-framework-chain] works tog [view-permissions-blogpost]: http://blog.nyaruka.com/adding-a-view-permission-to-django-models [nullbooleanselect]: https://github.com/django/django/blob/master/django/forms/widgets.py [search-django-admin]: https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.search_fields -[django-rest-framework-chain]: https://github.com/philipn/django-rest-framework-chain +[django-rest-framework-filters]: https://github.com/philipn/django-rest-framework-filters -- cgit v1.2.3 From 2b28026fc10c2a8d3e4c9ef1f11b2f802a40ec77 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Tue, 13 Jan 2015 10:44:40 +0000 Subject: Translation info -> project management --- docs/topics/project-management.md | 55 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/topics/project-management.md b/docs/topics/project-management.md index f581cabd..7f705196 100644 --- a/docs/topics/project-management.md +++ b/docs/topics/project-management.md @@ -63,10 +63,11 @@ The following template should be used for the description of the issue, and serv Team members have the following responsibilities. -* Add triage labels and milestones to tickets. * Close invalid or resolved tickets. +* Add triage labels and milestones to tickets. * Merge finalized pull requests. * Build and deploy the documentation, using `mkdocs gh-deploy`. +* Build and update the included translation packs. Further notes for maintainers: @@ -112,6 +113,55 @@ When pushing the release to PyPI ensure that your environment has been installed --- +## Translations + +The maintenance team are responsible for managing the translation packs include in REST framework. Translating the source strings into multiple languages is managed through the [transifex service][transifex-project]. + +### Managing Transifex + +The [official Transifex client][transifex-client] is used to upload and download translations to Transifex. The client is installed using pip: + + pip install transifex-client + +To use it you'll need a login to Transifex which has a password, and you'll need to have administrative access to the Transifex project. You'll need to create a `~/.transifexrc` file which contains your credentials. + + [https://www.transifex.com] + username = *** + token = *** + password = *** + hostname = https://www.transifex.com + +### Upload new source files + +When any user visible strings are changed, they should be uploaded to Transifex so that the translators can start to translate them. To do this, just run: + + # 1. Update the source django.po file, which is the US English version. + cd rest_framework + django-admin.py makemessages -l en_US + # 2. Push the source django.po file to Transifex. + cd .. + tx push -s + +When pushing source files, Transifex will update the source strings of a resource to match those from the new source file. + +Here's how differences between the old and new source files will be handled: + +* New strings will be added. +* Modified strings will be added as well. +* Strings which do not exist in the new source file will be removed from the database, along with their translations. If that source strings gets re-added later then [Transifex Translation Memory][translation-memory] will automatically include the translation string. + +### Download translations + +When a translator has finished translating their work needs to be downloaded from Transifex into the REST framework repository. To do this, run: + + # 3. Pull the translated django.po files from Transifex. + tx pull -a + cd rest_framework + # 4. Compile the binary .mo files for all supported languages. + django-admin.py compilemessages + +--- + ## Project ownership The PyPI package is owned by `@tomchristie`. As a backup `@j4mie` also has ownership of the package. @@ -129,6 +179,9 @@ The following issues still need to be addressed: [bus-factor]: http://en.wikipedia.org/wiki/Bus_factor [un-triaged]: https://github.com/tomchristie/django-rest-framework/issues?q=is%3Aopen+no%3Alabel +[transifex-project]: https://www.transifex.com/projects/p/django-rest-framework/ +[transifex-client]: https://pypi.python.org/pypi/transifex-client +[translation-memory]: http://docs.transifex.com/guides/tm#let-tm-automatically-populate-translations [github-org]: https://github.com/tomchristie/django-rest-framework/issues/2162 [sandbox]: http://restframework.herokuapp.com/ [mailing-list]: https://groups.google.com/forum/#!forum/django-rest-framework -- cgit v1.2.3 From 8e2dc6b26dd546f6b31aa6d1feb881b181f3ea21 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Tue, 13 Jan 2015 12:07:25 +0000 Subject: Update internationalization docs --- docs/index.md | 1 + docs/topics/internationalisation.md | 95 ------------------------------------- docs/topics/internationalization.md | 72 ++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 95 deletions(-) delete mode 100644 docs/topics/internationalisation.md create mode 100644 docs/topics/internationalization.md (limited to 'docs') diff --git a/docs/index.md b/docs/index.md index 544204c6..16376985 100644 --- a/docs/index.md +++ b/docs/index.md @@ -305,6 +305,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [settings]: api-guide/settings.md [documenting-your-api]: topics/documenting-your-api.md +[internationalization]: topics/documenting-your-api.md [ajax-csrf-cors]: topics/ajax-csrf-cors.md [browser-enhancements]: topics/browser-enhancements.md [browsableapi]: topics/browsable-api.md diff --git a/docs/topics/internationalisation.md b/docs/topics/internationalisation.md deleted file mode 100644 index 2a476c86..00000000 --- a/docs/topics/internationalisation.md +++ /dev/null @@ -1,95 +0,0 @@ -# Internationalisation -REST framework ships with translatable error messages. You can make these appear in your language enabling [Django's standard translation mechanisms][django-translation] and by translating the messages into your language. - -## How to translate REST Framework errors - -REST framework translations are managed online using [Transifex.com][transifex]. To get started, checkout the guide in the [CONTRIBUTING.md guide][contributing]. - -Sometimes you may want to use REST Framework in a language which has not been translated yet on Transifex. If that is the case then you should translate the error messages locally. - -#### How to translate REST Framework error messages locally: - -This guide assumes you are already familiar with how to translate a Django app. If you're not, start by reading [Django's translation docs][django-translation]. - -1. Make a new folder where you want to store the translated errors. Add this -path to your [`LOCALE_PATHS`][django-locale-paths] setting. - - --- - - **Note:** For the rest of -this document we will assume the path you created was -`/home/www/project/conf/locale/`, and that you have updated your `settings.py` to include the setting: - - ``` - LOCALE_PATHS = ( - '/home/www/project/conf/locale/', - ) - ``` - - --- - -2. Now create a subfolder for the language you want to translate. The folder should be named using [locale -name][django-locale-name] notation. E.g. `de`, `pt_BR`, `es_AR`, etc. - - ``` - mkdir /home/www/project/conf/locale/pt_BR/LC_MESSAGES - ``` - -3. Now copy the base translations file from the REST framework source code -into your translations folder - - ``` - cp /home/user/.virtualenvs/myproject/lib/python2.7/site-packages/rest_framework/locale/en_US/LC_MESSAGES/django.po - /home/www/project/conf/locale/pt_BR/LC_MESSAGES - ``` - - This should create the file - `/home/www/project/conf/locale/pt_BR/LC_MESSAGES/django.po` - - --- - - **Note:** To find out where `rest_framework` is installed, run - - ``` - python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())" - ``` - - --- - - -4. Edit `/home/www/project/conf/locale/pt_BR/LC_MESSAGES/django.po` and -translate all the error messages. - -5. Run `manage.py compilemessages -l pt_BR` to make the translations -available for Django to use. You should see a message - - ``` - processing file django.po in /home/www/project/conf/locale/pt_BR/LC_MESSAGES - ``` - -6. Restart your server. - - - -## How Django chooses which language to use -REST framework will use the same preferences to select which language to -display as Django does. You can find more info in the [Django docs on discovering language preferences][django-language-preference]. For reference, these are - -1. First, it looks for the language prefix in the requested URL -2. Failing that, it looks for the `LANGUAGE_SESSION_KEY` key in the current user’s session. -3. Failing that, it looks for a cookie -4. Failing that, it looks at the `Accept-Language` HTTP header. -5. Failing that, it uses the global `LANGUAGE_CODE` setting. - ---- - -**Note:** You'll need to include the `django.middleware.locale.LocaleMiddleware` to enable any of the per-request language preferences. - ---- - - -[django-translation]: https://docs.djangoproject.com/en/1.7/topics/i18n/translation -[django-language-preference]: https://docs.djangoproject.com/en/1.7/topics/i18n/translation/#how-django-discovers-language-preference -[django-locale-paths]: https://docs.djangoproject.com/en/1.7/ref/settings/#std:setting-LOCALE_PATHS -[django-locale-name]: https://docs.djangoproject.com/en/1.7/topics/i18n/#term-locale-name -[contributing]: ../../CONTRIBUTING.md diff --git a/docs/topics/internationalization.md b/docs/topics/internationalization.md new file mode 100644 index 00000000..fdde6c43 --- /dev/null +++ b/docs/topics/internationalization.md @@ -0,0 +1,72 @@ +# Internationalization + +> Supporting internationalization is not optional. It must be a core feature. +> +> — [Jannis Leidel, speaking at Django Under the Hood, 2015][cite]. + +REST framework ships with translatable error messages. You can make these appear in your language enabling [Django's standard translation mechanisms][django-translation]. + +Doing so will allow you to: + +* Select a language other than English as the default, using the standard `LANGUAGE_CODE` Django setting. +* Allow clients to choose a language themselves, using the `LocaleMiddleware` included with Django. A typical usage for API clients would be to include an `Accept-Language` request header. + +Note that the translations only apply to the error strings themselves. The format of error messages, and the keys of field names will remain the same. An example `400 Bad Request` response body might look like this: + + {"detail": {"username": ["Esse campo deve ser unico."]}} + +If you want to use different string for parts of the response such as `detail` and `non_field_errors` then you can modify this behavior by using a [custom exception handler][custom-exception-handler]. + +## Adding new translations + +REST framework translations are managed online using [Transifex][transifex-project]. You can use the Transifex service to add new translation languages. The maintenance team will then ensure that these translation strings are included in the REST framework package. + +Sometimes you may need to add translation strings to your project locally. You may need to do this if: + +* You want to use REST Framework in a language which has not been translated yet on Transifex. +* Your project includes custom error messages, which are not part of REST framework's default translation strings. + +#### Translating a new language locally + +This guide assumes you are already familiar with how to translate a Django app. If you're not, start by reading [Django's translation docs][django-translation]. + +If you're translating a new language you'll need to translate the existing REST framework error messages: + +1. Make a new folder where you want to store the internationalization resources. Add this path to your [`LOCALE_PATHS`][django-locale-paths] setting. + +2. Now create a subfolder for the language you want to translate. The folder should be named using [locale name][django-locale-name] notation. For example: `de`, `pt_BR`, `es_AR`. + +3. Now copy the [base translations file][django-po-source] from the REST framework source code into your translations folder. + +4. Edit the `django.po` file you've just copied, translating all the error messages. + +5. Run `manage.py compilemessages -l pt_BR` to make the translations +available for Django to use. You should see a message like `processing file django.po in <...>/locale/pt_BR/LC_MESSAGES`. + +6. Restart your development server to see the changes take effect. + +If you're only translating custom error messages that exist inside your project codebase you don't need to copy the REST framework source `django.po` file into a `LOCALE_PATHS` folder, and can instead simply run Django's standard `makemessages` process. + +## How the language is determined + +If you want to allow per-request language preferences you'll need to include `django.middleware.locale.LocaleMiddleware` in your `MIDDLEWARE_CLASSES` setting. + +You can find more information on how the language preference is determined in the [Django documentation][django-language-preference]. For reference, the method is: + +1. First, it looks for the language prefix in the requested URL. +2. Failing that, it looks for the `LANGUAGE_SESSION_KEY` key in the current user’s session. +3. Failing that, it looks for a cookie. +4. Failing that, it looks at the `Accept-Language` HTTP header. +5. Failing that, it uses the global `LANGUAGE_CODE` setting. + +For API clients the most appropriate of these will typically be to use the `Accept-Language` header; Sessions and cookies will not be available unless using session authentication, and generally better practice to prefer an `Accept-Language` header for API clients rather than using language URL prefixes. + +[cite]: http://youtu.be/Wa0VfS2q94Y +[django-translation]: https://docs.djangoproject.com/en/1.7/topics/i18n/translation +[custom-exception-handler]: ../api-guide/exceptions.md#custom-exception-handling +[transifex-project]: https://www.transifex.com/projects/p/django-rest-framework/ +[django-po-source]: https://raw.githubusercontent.com/tomchristie/django-rest-framework/master/rest_framework/locale/en_US/LC_MESSAGES/django.po +[django-language-preference]: https://docs.djangoproject.com/en/1.7/topics/i18n/translation/#how-django-discovers-language-preference +[django-locale-paths]: https://docs.djangoproject.com/en/1.7/ref/settings/#std:setting-LOCALE_PATHS +[django-locale-name]: https://docs.djangoproject.com/en/1.7/topics/i18n/#term-locale-name +[contributing]: ../../CONTRIBUTING.md -- cgit v1.2.3 From 564f845e21cd55669311db9491b85dc86a5ff628 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Tue, 13 Jan 2015 12:21:03 +0000 Subject: Lower header font weights for nicer docs style --- docs/topics/3.1-announcement.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 docs/topics/3.1-announcement.md (limited to 'docs') diff --git a/docs/topics/3.1-announcement.md b/docs/topics/3.1-announcement.md new file mode 100644 index 00000000..a0ad9829 --- /dev/null +++ b/docs/topics/3.1-announcement.md @@ -0,0 +1,7 @@ +# Versioning + +# Pagination + +# Internationalization + +# ModelSerializer API -- cgit v1.2.3 From 1bcec3a0ac4346b31b655a08505d3e3dc2156604 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Tue, 13 Jan 2015 17:14:13 +0000 Subject: API tweaks and pagination documentation --- docs/api-guide/pagination.md | 162 ++++++++++++++++--------------------------- 1 file changed, 58 insertions(+), 104 deletions(-) (limited to 'docs') diff --git a/docs/api-guide/pagination.md b/docs/api-guide/pagination.md index 83429292..9fbeb22a 100644 --- a/docs/api-guide/pagination.md +++ b/docs/api-guide/pagination.md @@ -6,148 +6,101 @@ source: pagination.py > > — [Django documentation][cite] -REST framework includes a `PaginationSerializer` class that makes it easy to return paginated data in a way that can then be rendered to arbitrary media types. +REST framework includes support for customizable pagination styles. This allows you to modify how large result sets are split into individual pages of data. -## Paginating basic data +The pagination API can support either: -Let's start by taking a look at an example from the Django documentation. +* Pagination links that are provided as part of the content of the response. +* Pagination links that are included in response headers, such as `Content-Range` or `Link`. - from django.core.paginator import Paginator +The built-in styles currently all use links included as part of the content of the response. This style is more accessible when using the browsable API. - objects = ['john', 'paul', 'george', 'ringo'] - paginator = Paginator(objects, 2) - page = paginator.page(1) - page.object_list - # ['john', 'paul'] +Pagination is only performed automatically if you're using the generic views or viewsets. If you're using a regular `APIView`, you'll need to call into the pagination API yourself to ensure you return a paginated response. See the source code for the `mixins.ListMixin` and `generics.GenericAPIView` classes for an example. -At this point we've got a page object. If we wanted to return this page object as a JSON response, we'd need to provide the client with context such as next and previous links, so that it would be able to page through the remaining results. +## Setting the pagination style - from rest_framework.pagination import PaginationSerializer +The default pagination style may be set globally, using the `DEFAULT_PAGINATION_CLASS` settings key. For example, to use the built-in limit/offset pagination, you would do: - serializer = PaginationSerializer(instance=page) - serializer.data - # {'count': 4, 'next': '?page=2', 'previous': None, 'results': [u'john', u'paul']} - -The `context` argument of the `PaginationSerializer` class may optionally include the request. If the request is included in the context then the next and previous links returned by the serializer will use absolute URLs instead of relative URLs. - - request = RequestFactory().get('/foobar') - serializer = PaginationSerializer(instance=page, context={'request': request}) - serializer.data - # {'count': 4, 'next': 'http://testserver/foobar?page=2', 'previous': None, 'results': [u'john', u'paul']} - -We could now return that data in a `Response` object, and it would be rendered into the correct media type. - -## Paginating QuerySets - -Our first example worked because we were using primitive objects. If we wanted to paginate a queryset or other complex data, we'd need to specify a serializer to use to serialize the result set itself. - -We can do this using the `object_serializer_class` attribute on the inner `Meta` class of the pagination serializer. For example. - - class UserSerializer(serializers.ModelSerializer): - """ - Serializes user querysets. - """ - class Meta: - model = User - fields = ('username', 'email') + REST_FRAMEWORK = { + 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination' + } - class PaginatedUserSerializer(pagination.PaginationSerializer): - """ - Serializes page objects of user querysets. - """ - class Meta: - object_serializer_class = UserSerializer +You can also set the pagination class on an individual view by using the `pagination_class` attribute. Typically you'll want to use the same pagination style throughout your API, although you might want to vary individual aspects of the pagination, such as default or maximum page size, on a per-view basis. -We could now use our pagination serializer in a view like this. +## Modifying the pagination style - @api_view('GET') - def user_list(request): - queryset = User.objects.all() - paginator = Paginator(queryset, 20) +If you want to modify particular aspects of the pagination style, you'll want to override one of the pagination classes, and set the attributes that you want to change. - page = request.QUERY_PARAMS.get('page') - try: - users = paginator.page(page) - except PageNotAnInteger: - # If page is not an integer, deliver first page. - users = paginator.page(1) - except EmptyPage: - # If page is out of range (e.g. 9999), - # deliver last page of results. - users = paginator.page(paginator.num_pages) + class LargeResultsSetPagination(PageNumberPagination): + paginate_by = 1000 + paginate_by_param = 'page_size' + max_paginate_by = 10000 - serializer_context = {'request': request} - serializer = PaginatedUserSerializer(users, - context=serializer_context) - return Response(serializer.data) + class StandardResultsSetPagination(PageNumberPagination): + paginate_by = 100 + paginate_by_param = 'page_size' + max_paginate_by = 1000 -## Pagination in the generic views +You can then apply your new style to a view using the `.pagination_class` attribute: -The generic class based views `ListAPIView` and `ListCreateAPIView` provide pagination of the returned querysets by default. You can customise this behaviour by altering the pagination style, by modifying the default number of results, by allowing clients to override the page size using a query parameter, or by turning pagination off completely. + class BillingRecordsView(generics.ListAPIView): + queryset = Billing.objects.all() + serializer = BillingRecordsSerializer + pagination_class = LargeResultsSetPagination -The default pagination style may be set globally, using the `DEFAULT_PAGINATION_SERIALIZER_CLASS`, `PAGINATE_BY`, `PAGINATE_BY_PARAM`, and `MAX_PAGINATE_BY` settings. For example. +Or apply the style globally, using the `DEFAULT_PAGINATION_CLASS` settings key. For example: REST_FRAMEWORK = { - 'PAGINATE_BY': 10, # Default to 10 - 'PAGINATE_BY_PARAM': 'page_size', # Allow client to override, using `?page_size=xxx`. - 'MAX_PAGINATE_BY': 100 # Maximum limit allowed when using `?page_size=xxx`. - } - -You can also set the pagination style on a per-view basis, using the `ListAPIView` generic class-based view. + 'DEFAULT_PAGINATION_CLASS': 'apps.core.pagination.StandardResultsSetPagination' } - class PaginatedListView(ListAPIView): - queryset = ExampleModel.objects.all() - serializer_class = ExampleModelSerializer - paginate_by = 10 - paginate_by_param = 'page_size' - max_paginate_by = 100 +# API Reference -Note that using a `paginate_by` value of `None` will turn off pagination for the view. -Note if you use the `PAGINATE_BY_PARAM` settings, you also have to set the `paginate_by_param` attribute in your view to `None` in order to turn off pagination for those requests that contain the `paginate_by_param` parameter. +## PageNumberPagination -For more complex requirements such as serialization that differs depending on the requested media type you can override the `.get_paginate_by()` and `.get_pagination_serializer_class()` methods. +## LimitOffsetPagination --- -# Custom pagination serializers +# Custom pagination styles + +To create a custom pagination serializer class you should subclass `pagination.BasePagination` and override the `paginate_queryset(self, queryset, request, view)` and `get_paginated_response(self, data)` methods: -To create a custom pagination serializer class you should override `pagination.BasePaginationSerializer` and set the fields that you want the serializer to return. +* The `paginate_queryset` method is passed the initial queryset and should return an iterable object that contains only the data in the requested page. +* The `get_paginated_response` method is passed the serialized page data and should return a `Response` instance. -You can also override the name used for the object list field, by setting the `results_field` attribute, which defaults to `'results'`. +Note that the `paginate_queryset` method may set state on the pagination instance, that may later be used by the `get_paginated_response` method. ## Example -For example, to nest a pair of links labelled 'prev' and 'next', and set the name for the results field to 'objects', you might use something like this. +Let's modify the built-in `PageNumberPagination` style, so that instead of include the pagination links in the body of the response, we'll instead include a `Link` header, in a [similar style to the GitHub API][github-link-pagination]. - from rest_framework import pagination - from rest_framework import serializers + class LinkHeaderPagination(PageNumberPagination) + def get_paginated_response(self, data): + next_url = self.get_next_link() previous_url = self.get_previous_link() - class LinksSerializer(serializers.Serializer): - next = pagination.NextPageField(source='*') - prev = pagination.PreviousPageField(source='*') + if next_url is not None and previous_url is not None: + link = '<{next_url}; rel="next">, <{previous_url}; rel="prev">' + elif next_url is not None: + link = '<{next_url}; rel="next">' + elif prev_url is not None: + link = '<{previous_url}; rel="prev">' + else: + link = '' - class CustomPaginationSerializer(pagination.BasePaginationSerializer): - links = LinksSerializer(source='*') # Takes the page object as the source - total_results = serializers.ReadOnlyField(source='paginator.count') + link = link.format(next_url=next_url, previous_url=previous_url) + headers = {'Link': link} if link else {} - results_field = 'objects' + return Response(data, headers=headers) -## Using your custom pagination serializer +## Using your custom pagination class -To have your custom pagination serializer be used by default, use the `DEFAULT_PAGINATION_SERIALIZER_CLASS` setting: +To have your custom pagination class be used by default, use the `DEFAULT_PAGINATION_CLASS` setting: REST_FRAMEWORK = { - 'DEFAULT_PAGINATION_SERIALIZER_CLASS': - 'example_app.pagination.CustomPaginationSerializer', + 'DEFAULT_PAGINATION_CLASS': + 'my_project.apps.core.pagination.LinkHeaderPagination', } -Alternatively, to set your custom pagination serializer on a per-view basis, use the `pagination_serializer_class` attribute on a generic class based view: - - class PaginatedListView(generics.ListAPIView): - model = ExampleModel - pagination_serializer_class = CustomPaginationSerializer - paginate_by = 10 - # Third party packages The following third party packages are also available. @@ -157,5 +110,6 @@ The following third party packages are also available. The [`DRF-extensions` package][drf-extensions] includes a [`PaginateByMaxMixin` mixin class][paginate-by-max-mixin] that allows your API clients to specify `?page_size=max` to obtain the maximum allowed page size. [cite]: https://docs.djangoproject.com/en/dev/topics/pagination/ +[github-link-pagination]: https://developer.github.com/guides/traversing-with-pagination/ [drf-extensions]: http://chibisov.github.io/drf-extensions/docs/ [paginate-by-max-mixin]: http://chibisov.github.io/drf-extensions/docs/#paginatebymaxmixin -- cgit v1.2.3 From 313aa727e3c44016e531a7af75051fc6e6d7cb96 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 14 Jan 2015 17:46:41 +0000 Subject: Tweaks --- docs/api-guide/pagination.md | 19 +++++++++++++++---- docs/img/link-header-pagination.png | Bin 0 -> 35799 bytes 2 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 docs/img/link-header-pagination.png (limited to 'docs') diff --git a/docs/api-guide/pagination.md b/docs/api-guide/pagination.md index 9fbeb22a..ba71a303 100644 --- a/docs/api-guide/pagination.md +++ b/docs/api-guide/pagination.md @@ -74,7 +74,7 @@ Note that the `paginate_queryset` method may set state on the pagination instanc Let's modify the built-in `PageNumberPagination` style, so that instead of include the pagination links in the body of the response, we'll instead include a `Link` header, in a [similar style to the GitHub API][github-link-pagination]. - class LinkHeaderPagination(PageNumberPagination) + class LinkHeaderPagination(pagination.PageNumberPagination): def get_paginated_response(self, data): next_url = self.get_next_link() previous_url = self.get_previous_link() @@ -82,7 +82,7 @@ Let's modify the built-in `PageNumberPagination` style, so that instead of inclu link = '<{next_url}; rel="next">, <{previous_url}; rel="prev">' elif next_url is not None: link = '<{next_url}; rel="next">' - elif prev_url is not None: + elif previous_url is not None: link = '<{previous_url}; rel="prev">' else: link = '' @@ -97,10 +97,20 @@ Let's modify the built-in `PageNumberPagination` style, so that instead of inclu To have your custom pagination class be used by default, use the `DEFAULT_PAGINATION_CLASS` setting: REST_FRAMEWORK = { - 'DEFAULT_PAGINATION_CLASS': - 'my_project.apps.core.pagination.LinkHeaderPagination', + 'DEFAULT_PAGINATION_CLASS': 'my_project.apps.core.pagination.LinkHeaderPagination', + 'PAGINATE_BY': 10 } +API responses for list endpoints will now include a `Link` header, instead of including the pagination links as part of the body of the response, for example: + +--- + +![Link Header][link-header] + +*A custom pagination style, using the 'Link' header'* + +--- + # Third party packages The following third party packages are also available. @@ -111,5 +121,6 @@ The [`DRF-extensions` package][drf-extensions] includes a [`PaginateByMaxMixin` [cite]: https://docs.djangoproject.com/en/dev/topics/pagination/ [github-link-pagination]: https://developer.github.com/guides/traversing-with-pagination/ +[link-header]: ../img/link-header-pagination.png [drf-extensions]: http://chibisov.github.io/drf-extensions/docs/ [paginate-by-max-mixin]: http://chibisov.github.io/drf-extensions/docs/#paginatebymaxmixin diff --git a/docs/img/link-header-pagination.png b/docs/img/link-header-pagination.png new file mode 100644 index 00000000..d3c556a4 Binary files /dev/null and b/docs/img/link-header-pagination.png differ -- cgit v1.2.3 From 53edd37df5aa0ac29dbe7824db2e33da1d901f98 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 15 Jan 2015 21:07:05 +0000 Subject: Tests for LimitOffsetPagination --- docs/api-guide/pagination.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/api-guide/pagination.md b/docs/api-guide/pagination.md index ba71a303..8ab2edd5 100644 --- a/docs/api-guide/pagination.md +++ b/docs/api-guide/pagination.md @@ -63,7 +63,7 @@ Or apply the style globally, using the `DEFAULT_PAGINATION_CLASS` settings key. # Custom pagination styles -To create a custom pagination serializer class you should subclass `pagination.BasePagination` and override the `paginate_queryset(self, queryset, request, view)` and `get_paginated_response(self, data)` methods: +To create a custom pagination serializer class you should subclass `pagination.BasePagination` and override the `paginate_queryset(self, queryset, request, view=None)` and `get_paginated_response(self, data)` methods: * The `paginate_queryset` method is passed the initial queryset and should return an iterable object that contains only the data in the requested page. * The `get_paginated_response` method is passed the serialized page data and should return a `Response` instance. -- cgit v1.2.3 From b0bc79ed4dade0636fc45bc001ef659aa664cd4a Mon Sep 17 00:00:00 2001 From: Eric Theise Date: Mon, 19 Jan 2015 14:49:36 -0800 Subject: correcting "it's" to "its" in Tutorial 1 --- docs/tutorial/1-serialization.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/tutorial/1-serialization.md b/docs/tutorial/1-serialization.md index 41ff4d07..80e869ea 100644 --- a/docs/tutorial/1-serialization.md +++ b/docs/tutorial/1-serialization.md @@ -198,7 +198,7 @@ Open the file `snippets/serializers.py` again, and replace the `SnippetSerialize model = Snippet fields = ('id', 'title', 'code', 'linenos', 'language', 'style') -One nice property that serializers have is that you can inspect all the fields in a serializer instance, by printing it's representation. Open the Django shell with `python manage.py shell`, then try the following: +One nice property that serializers have is that you can inspect all the fields in a serializer instance, by printing its representation. Open the Django shell with `python manage.py shell`, then try the following: >>> from snippets.serializers import SnippetSerializer >>> serializer = SnippetSerializer() -- cgit v1.2.3 From 3ca8f85a5b54e6f78fac273732b6c5be2ad25ae4 Mon Sep 17 00:00:00 2001 From: soooooot Date: Tue, 20 Jan 2015 22:24:58 +0800 Subject: correcting unclosed quote in routers.md correcting unclosed quote in routers.md--- docs/api-guide/routers.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs') diff --git a/docs/api-guide/routers.md b/docs/api-guide/routers.md index 3a8a8f6c..9c9bfb50 100644 --- a/docs/api-guide/routers.md +++ b/docs/api-guide/routers.md @@ -60,7 +60,7 @@ For example, you can append `router.urls` to a list of existing views… router.register(r'accounts', AccountViewSet) urlpatterns = [ - url(r'^forgot-password/$, ForgotPasswordFormView.as_view(), + url(r'^forgot-password/$', ForgotPasswordFormView.as_view(), ] urlpatterns += router.urls @@ -68,14 +68,14 @@ For example, you can append `router.urls` to a list of existing views… Alternatively you can use Django's `include` function, like so… urlpatterns = [ - url(r'^forgot-password/$, ForgotPasswordFormView.as_view(), + url(r'^forgot-password/$', ForgotPasswordFormView.as_view(), url(r'^', include(router.urls)) ] Router URL patterns can also be namespaces. urlpatterns = [ - url(r'^forgot-password/$, ForgotPasswordFormView.as_view(), + url(r'^forgot-password/$', ForgotPasswordFormView.as_view(), url(r'^api/', include(router.urls, namespace='api')) ] -- cgit v1.2.3 From 6e471ad8f41dda11365080ca583a0ccbf37de55e Mon Sep 17 00:00:00 2001 From: Duncan Maitland Date: Thu, 22 Jan 2015 18:29:20 +1100 Subject: fix link to Django CSRF docs --- docs/api-guide/authentication.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/api-guide/authentication.md b/docs/api-guide/authentication.md index 1222dbf0..0d53de70 100755 --- a/docs/api-guide/authentication.md +++ b/docs/api-guide/authentication.md @@ -427,7 +427,7 @@ HTTP Signature (currently a [IETF draft][http-signature-ietf-draft]) provides a [oauth]: http://oauth.net/2/ [permission]: permissions.md [throttling]: throttling.md -[csrf-ajax]: https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax +[csrf-ajax]: https://docs.djangoproject.com/en/dev/ref/csrf/#ajax [mod_wsgi_official]: http://code.google.com/p/modwsgi/wiki/ConfigurationDirectives#WSGIPassAuthorization [custom-user-model]: https://docs.djangoproject.com/en/dev/topics/auth/customizing/#specifying-a-custom-user-model [south-dependencies]: http://south.readthedocs.org/en/latest/dependencies.html -- cgit v1.2.3 From 790c92d438f85c93d8c3cf626347915c65c8384d Mon Sep 17 00:00:00 2001 From: Carlton Gibson Date: Fri, 23 Jan 2015 15:22:20 +0100 Subject: Update Django-Filter references in docs and requirements. --- docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/index.md b/docs/index.md index d40f8972..c1110788 100644 --- a/docs/index.md +++ b/docs/index.md @@ -58,7 +58,7 @@ The following packages are optional: * [Markdown][markdown] (2.1.0+) - Markdown support for the browsable API. * [PyYAML][yaml] (3.10+) - YAML content-type support. * [defusedxml][defusedxml] (0.3+) - XML content-type support. -* [django-filter][django-filter] (0.5.4+) - Filtering support. +* [django-filter][django-filter] (0.9.2+) - Filtering support. * [django-oauth-plus][django-oauth-plus] (2.0+) and [oauth2][oauth2] (1.5.211+) - OAuth 1.0a support. * [django-oauth2-provider][django-oauth2-provider] (0.2.3+) - OAuth 2.0 support. * [django-guardian][django-guardian] (1.1.1+) - Object level permissions support. -- cgit v1.2.3 From 5bb348605e5dad3b58495b1fc56ea393194b89fb Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 23 Jan 2015 15:31:08 +0000 Subject: UUIDField docs --- docs/api-guide/fields.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/api-guide/fields.md b/docs/api-guide/fields.md index b3d274dd..64ec902b 100644 --- a/docs/api-guide/fields.md +++ b/docs/api-guide/fields.md @@ -182,6 +182,12 @@ Corresponds to `django.db.models.fields.URLField`. Uses Django's `django.core.v **Signature:** `URLField(max_length=200, min_length=None, allow_blank=False)` +## UUIDField + +A field that ensures the input is a valid UUID string. The `to_internal_value` method will return a `uuid.UUID` instance. On output the field will return a string in the canonical hyphenated format, for example: + + "de305d54-75b4-431b-adb2-eb6b9e546013" + --- # Numeric fields @@ -320,7 +326,7 @@ Both the `allow_blank` and `allow_null` are valid options on `ChoiceField`, alth ## MultipleChoiceField -A field that can accept a set of zero, one or many values, chosen from a limited set of choices. Takes a single mandatory argument. `to_internal_representation` returns a `set` containing the selected values. +A field that can accept a set of zero, one or many values, chosen from a limited set of choices. Takes a single mandatory argument. `to_internal_value` returns a `set` containing the selected values. **Signature:** `MultipleChoiceField(choices)` -- cgit v1.2.3 From 35f6a8246299d31ecce4f791f9527bf34cebe6e2 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 23 Jan 2015 16:27:23 +0000 Subject: Added DictField and support for HStoreField. --- docs/api-guide/fields.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/api-guide/fields.md b/docs/api-guide/fields.md index 64ec902b..1c78a42b 100644 --- a/docs/api-guide/fields.md +++ b/docs/api-guide/fields.md @@ -380,7 +380,7 @@ A field class that validates a list of objects. **Signature**: `ListField(child)` -- `child` - A field instance that should be used for validating the objects in the list. +- `child` - A field instance that should be used for validating the objects in the list. If this argument is not provided then objects in the list will not be validated. For example, to validate a list of integers you might use something like the following: @@ -395,6 +395,23 @@ The `ListField` class also supports a declarative style that allows you to write We can now reuse our custom `StringListField` class throughout our application, without having to provide a `child` argument to it. +## DictField + +A field class that validates a dictionary of objects. The keys in `DictField` are always assumed to be string values. + +**Signature**: `DictField(child)` + +- `child` - A field instance that should be used for validating the values in the dictionary. If this argument is not provided then values in the mapping will not be validated. + +For example, to create a field that validates a mapping of strings to strings, you would write something like this: + + document = DictField(child=CharField()) + +You can also use the declarative style, as with `ListField`. For example: + + class DocumentField(DictField): + child = CharField() + --- # Miscellaneous fields -- cgit v1.2.3 From 39da9c7c865533d580ea410458aeb366835b18cc Mon Sep 17 00:00:00 2001 From: Jeff Fein-Worton Date: Sat, 24 Jan 2015 12:53:21 -0800 Subject: minor typo in viewsets docs --- docs/api-guide/viewsets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/api-guide/viewsets.md b/docs/api-guide/viewsets.md index 3e37cef8..b09dfc9e 100644 --- a/docs/api-guide/viewsets.md +++ b/docs/api-guide/viewsets.md @@ -146,7 +146,7 @@ The decorators can additionally take extra arguments that will be set for the ro def set_password(self, request, pk=None): ... -Theses decorators will route `GET` requests by default, but may also accept other HTTP methods, by using the `methods` argument. For example: +These decorators will route `GET` requests by default, but may also accept other HTTP methods, by using the `methods` argument. For example: @detail_route(methods=['post', 'delete']) def unset_password(self, request, pk=None): -- cgit v1.2.3 From 0a65913fea471e7545896bd88760be8b26a3225e Mon Sep 17 00:00:00 2001 From: Jeff Fein-Worton Date: Sat, 24 Jan 2015 18:34:16 -0800 Subject: typo in fields.md --- docs/api-guide/fields.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/api-guide/fields.md b/docs/api-guide/fields.md index 1c78a42b..10291c12 100644 --- a/docs/api-guide/fields.md +++ b/docs/api-guide/fields.md @@ -461,7 +461,7 @@ This is a read-only field. It gets its value by calling a method on the serializ **Signature**: `SerializerMethodField(method_name=None)` -- `method-name` - The name of the method on the serializer to be called. If not included this defaults to `get_`. +- `method_name` - The name of the method on the serializer to be called. If not included this defaults to `get_`. The serializer method referred to by the `method_name` argument should accept a single argument (in addition to `self`), which is the object being serialized. It should return whatever you want to be included in the serialized representation of the object. For example: -- cgit v1.2.3 From fc70c0862ff3e6183b79adc4675a63874261ddf0 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 26 Jan 2015 14:07:21 +0000 Subject: Galileo Press -> Rheinwerk Verlag --- docs/img/sponsors/2-galileo_press.png | Bin 11451 -> 0 bytes docs/img/sponsors/2-rheinwerk_verlag.png | Bin 0 -> 1562 bytes docs/topics/kickstarter-announcement.md | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 docs/img/sponsors/2-galileo_press.png create mode 100644 docs/img/sponsors/2-rheinwerk_verlag.png (limited to 'docs') diff --git a/docs/img/sponsors/2-galileo_press.png b/docs/img/sponsors/2-galileo_press.png deleted file mode 100644 index f77e6c0a..00000000 Binary files a/docs/img/sponsors/2-galileo_press.png and /dev/null differ diff --git a/docs/img/sponsors/2-rheinwerk_verlag.png b/docs/img/sponsors/2-rheinwerk_verlag.png new file mode 100644 index 00000000..ad454e17 Binary files /dev/null and b/docs/img/sponsors/2-rheinwerk_verlag.png differ diff --git a/docs/topics/kickstarter-announcement.md b/docs/topics/kickstarter-announcement.md index 9f99e3e6..78c5cce6 100644 --- a/docs/topics/kickstarter-announcement.md +++ b/docs/topics/kickstarter-announcement.md @@ -84,7 +84,7 @@ Our gold sponsors include companies large and small. Many thanks for their signi
  • Pulsecode Inc.
  • Singing Horse Studio Ltd.
  • Heroku
  • -
  • Galileo Press
  • +
  • Rheinwerk Verlag
  • Security Compass
  • Django Software Foundation
  • Hipflask
  • -- cgit v1.2.3 From 925ea4bdc6d40a1e118087f28a09c86977dc5532 Mon Sep 17 00:00:00 2001 From: Xavier Ordoquy Date: Tue, 27 Jan 2015 19:43:38 +0100 Subject: Release notes for 3.0.4 --- docs/topics/release-notes.md | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'docs') diff --git a/docs/topics/release-notes.md b/docs/topics/release-notes.md index c49dd62c..e0894d2d 100644 --- a/docs/topics/release-notes.md +++ b/docs/topics/release-notes.md @@ -41,6 +41,24 @@ You can determine your currently installed version using `pip freeze`: ## 3.0.x series +### 3.0.4 + +**Date**: [28th January 2015][3.0.4-milestone]. + +* Django 1.8a1 support. ([#2425][gh2425], [#2446][gh2446], [#2441][gh2441]) +* Add `DictField` and support Django 1.8 `HStoreField`. ([#2451][gh2451], [#2106][gh2106]) +* Add `UUIDField` and support Django 1.8 `UUIDField`. ([#2448][gh2448], [#2433][gh2433], [#2432][gh2432]) +* `BaseRenderer.render` now raises `NotImplementedError`. ([#2434][gh2434]) +* Fix timedelta JSON serialization on Python 2.6. ([#2430][gh2430]) +* `ResultDict` and `ResultList` now appear as standard dict/list. ([#2421][gh2421]) +* Fix visible `HiddenField` in the HTML form of the web browsable API page. ([#2410][gh2410]) +* Use `OrderedDict` for `RelatedField.choices`. ([#2408][gh2408]) +* Fix ident format when using `HTTP_X_FORWARDED_FOR`. ([#2401][gh2401]) +* Fix invalid key with memcached while using throttling. ([#2400][gh2400]) +* Fix `FileUploadParser` with version 3.x. ([#2399][gh2399]) +* Fix the serializer inheritance. ([#2388][gh2388]) +* Fix caching issues with `ReturnDict`. ([#2360][gh2360]) + ### 3.0.3 **Date**: [8th January 2015][3.0.3-milestone]. @@ -702,6 +720,7 @@ For older release notes, [please see the GitHub repo](old-release-notes). [3.0.1-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.0.1+Release%22 [3.0.2-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.0.2+Release%22 [3.0.3-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.0.3+Release%22 +[3.0.4-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.0.4+Release%22 [gh2013]: https://github.com/tomchristie/django-rest-framework/issues/2013 @@ -770,3 +789,22 @@ For older release notes, [please see the GitHub repo](old-release-notes). [gh2355]: https://github.com/tomchristie/django-rest-framework/issues/2355 [gh2369]: https://github.com/tomchristie/django-rest-framework/issues/2369 [gh2386]: https://github.com/tomchristie/django-rest-framework/issues/2386 + +[gh2425]: https://github.com/tomchristie/django-rest-framework/issues/2425 +[gh2446]: https://github.com/tomchristie/django-rest-framework/issues/2446 +[gh2441]: https://github.com/tomchristie/django-rest-framework/issues/2441 +[gh2451]: https://github.com/tomchristie/django-rest-framework/issues/2451 +[gh2106]: https://github.com/tomchristie/django-rest-framework/issues/2106 +[gh2448]: https://github.com/tomchristie/django-rest-framework/issues/2448 +[gh2433]: https://github.com/tomchristie/django-rest-framework/issues/2433 +[gh2432]: https://github.com/tomchristie/django-rest-framework/issues/2432 +[gh2434]: https://github.com/tomchristie/django-rest-framework/issues/2434 +[gh2430]: https://github.com/tomchristie/django-rest-framework/issues/2430 +[gh2421]: https://github.com/tomchristie/django-rest-framework/issues/2421 +[gh2410]: https://github.com/tomchristie/django-rest-framework/issues/2410 +[gh2408]: https://github.com/tomchristie/django-rest-framework/issues/2408 +[gh2401]: https://github.com/tomchristie/django-rest-framework/issues/2401 +[gh2400]: https://github.com/tomchristie/django-rest-framework/issues/2400 +[gh2399]: https://github.com/tomchristie/django-rest-framework/issues/2399 +[gh2388]: https://github.com/tomchristie/django-rest-framework/issues/2388 +[gh2360]: https://github.com/tomchristie/django-rest-framework/issues/2360 -- cgit v1.2.3 From 0daf160946db4f2fed6a237136d738d954b841c0 Mon Sep 17 00:00:00 2001 From: Xavier Ordoquy Date: Wed, 28 Jan 2015 00:06:34 +0100 Subject: Fix #2476 --- docs/api-guide/routers.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'docs') diff --git a/docs/api-guide/routers.md b/docs/api-guide/routers.md index 9c9bfb50..a9f911a9 100644 --- a/docs/api-guide/routers.md +++ b/docs/api-guide/routers.md @@ -60,7 +60,7 @@ For example, you can append `router.urls` to a list of existing views… router.register(r'accounts', AccountViewSet) urlpatterns = [ - url(r'^forgot-password/$', ForgotPasswordFormView.as_view(), + url(r'^forgot-password/$', ForgotPasswordFormView.as_view()), ] urlpatterns += router.urls @@ -68,15 +68,15 @@ For example, you can append `router.urls` to a list of existing views… Alternatively you can use Django's `include` function, like so… urlpatterns = [ - url(r'^forgot-password/$', ForgotPasswordFormView.as_view(), - url(r'^', include(router.urls)) + url(r'^forgot-password/$', ForgotPasswordFormView.as_view()), + url(r'^', include(router.urls)), ] Router URL patterns can also be namespaces. urlpatterns = [ - url(r'^forgot-password/$', ForgotPasswordFormView.as_view(), - url(r'^api/', include(router.urls, namespace='api')) + url(r'^forgot-password/$', ForgotPasswordFormView.as_view()), + url(r'^api/', include(router.urls, namespace='api')), ] If using namespacing with hyperlinked serializers you'll also need to ensure that any `view_name` parameters on the serializers correctly reflect the namespace. In the example above you'd need to include a parameter such as `view_name='api:user-detail'` for serializer fields hyperlinked to the user detail view. -- cgit v1.2.3 From 4a2a36ef828ce0e687c48fdb597d343df65f0e2b Mon Sep 17 00:00:00 2001 From: mareknaskret Date: Wed, 28 Jan 2015 15:17:56 +0100 Subject: Update filtering.md Updated links for django-guardian package.--- docs/api-guide/filtering.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs') diff --git a/docs/api-guide/filtering.md b/docs/api-guide/filtering.md index e00560c7..b16b6be5 100644 --- a/docs/api-guide/filtering.md +++ b/docs/api-guide/filtering.md @@ -398,8 +398,8 @@ The [django-rest-framework-filters package][django-rest-framework-filters] works [cite]: https://docs.djangoproject.com/en/dev/topics/db/queries/#retrieving-specific-objects-with-filters [django-filter]: https://github.com/alex/django-filter [django-filter-docs]: https://django-filter.readthedocs.org/en/latest/index.html -[guardian]: http://pythonhosted.org/django-guardian/ -[view-permissions]: http://pythonhosted.org/django-guardian/userguide/assign.html +[guardian]: https://django-guardian.readthedocs.org/ +[view-permissions]: https://django-guardian.readthedocs.org/en/latest/userguide/assign.html [view-permissions-blogpost]: http://blog.nyaruka.com/adding-a-view-permission-to-django-models [nullbooleanselect]: https://github.com/django/django/blob/master/django/forms/widgets.py [search-django-admin]: https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.search_fields -- cgit v1.2.3 From e720927b78a31999f03bfa248329d623ce2c045c Mon Sep 17 00:00:00 2001 From: Tymur Maryokhin Date: Thu, 29 Jan 2015 17:28:18 +0100 Subject: Removed deprecated '.model' docs --- docs/api-guide/generic-views.md | 8 ++------ docs/api-guide/routers.md | 2 +- docs/topics/3.0-announcement.md | 2 +- 3 files changed, 4 insertions(+), 8 deletions(-) (limited to 'docs') diff --git a/docs/api-guide/generic-views.md b/docs/api-guide/generic-views.md index 6374e305..61c8e8d8 100755 --- a/docs/api-guide/generic-views.md +++ b/docs/api-guide/generic-views.md @@ -93,17 +93,13 @@ The following attributes are used to control pagination when used with list view * `filter_backends` - A list of filter backend classes that should be used for filtering the queryset. Defaults to the same value as the `DEFAULT_FILTER_BACKENDS` setting. -**Deprecated attributes**: - -* `model` - This shortcut may be used instead of setting either (or both) of the `queryset`/`serializer_class` attributes. The explicit style is preferred over the `.model` shortcut, and usage of this attribute is now deprecated. - ### Methods **Base methods**: #### `get_queryset(self)` -Returns the queryset that should be used for list views, and that should be used as the base for lookups in detail views. Defaults to returning the queryset specified by the `queryset` attribute, or the default queryset for the model if the `model` shortcut is being used. +Returns the queryset that should be used for list views, and that should be used as the base for lookups in detail views. Defaults to returning the queryset specified by the `queryset` attribute. This method should always be used rather than accessing `self.queryset` directly, as `self.queryset` gets evaluated only once, and those results are cached for all subsequent requests. @@ -153,7 +149,7 @@ For example: #### `get_serializer_class(self)` -Returns the class that should be used for the serializer. Defaults to returning the `serializer_class` attribute, or dynamically generating a serializer class if the `model` shortcut is being used. +Returns the class that should be used for the serializer. Defaults to returning the `serializer_class` attribute. May be overridden to provide dynamic behavior, such as using different serializers for read and write operations, or providing different serializers to different types of users. diff --git a/docs/api-guide/routers.md b/docs/api-guide/routers.md index a9f911a9..592f7d66 100644 --- a/docs/api-guide/routers.md +++ b/docs/api-guide/routers.md @@ -28,7 +28,7 @@ There are two mandatory arguments to the `register()` method: Optionally, you may also specify an additional argument: -* `base_name` - The base to use for the URL names that are created. If unset the basename will be automatically generated based on the `model` or `queryset` attribute on the viewset, if it has one. Note that if the viewset does not include a `model` or `queryset` attribute then you must set `base_name` when registering the viewset. +* `base_name` - The base to use for the URL names that are created. If unset the basename will be automatically generated based on the `queryset` attribute of the viewset, if it has one. Note that if the viewset does not include a `queryset` attribute then you must set `base_name` when registering the viewset. The example above would generate the following URL patterns: diff --git a/docs/topics/3.0-announcement.md b/docs/topics/3.0-announcement.md index 5dbc5600..24e69c2d 100644 --- a/docs/topics/3.0-announcement.md +++ b/docs/topics/3.0-announcement.md @@ -665,7 +665,7 @@ This code *would be valid* in `2.4.3`: class Meta: model = Account -However this code *would not be valid* in `2.4.3`: +However this code *would not be valid* in `3.0`: # Missing `queryset` class AccountSerializer(serializers.Serializer): -- cgit v1.2.3 From 7cf9dea7f905ea6869148a68b4fa96cad0a347e8 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 30 Jan 2015 11:00:29 +0000 Subject: Docs typo. Closes #2491. --- docs/api-guide/parsers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/api-guide/parsers.md b/docs/api-guide/parsers.md index 73e3a705..3d44fe56 100644 --- a/docs/api-guide/parsers.md +++ b/docs/api-guide/parsers.md @@ -128,7 +128,7 @@ If the view used with `FileUploadParser` is called with a `filename` URL keyword def put(self, request, filename, format=None): file_obj = request.data['file'] # ... - # do some staff with uploaded file + # do some stuff with uploaded file # ... return Response(status=204) -- cgit v1.2.3 From 0d96cf2ca2e3298ed38e81482bcdc2664d060735 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 30 Jan 2015 16:27:49 +0000 Subject: Latest translation source messages. --- docs/topics/3.1-announcement.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'docs') diff --git a/docs/topics/3.1-announcement.md b/docs/topics/3.1-announcement.md index a0ad9829..3eb52f4c 100644 --- a/docs/topics/3.1-announcement.md +++ b/docs/topics/3.1-announcement.md @@ -1,7 +1,15 @@ -# Versioning +# Django REST framework 3.1 -# Pagination +## Pagination -# Internationalization +#### Pagination controls in the browsable API. -# ModelSerializer API +#### New pagination schemes. + +#### Support for header-based pagination. + +## Versioning + +## Internationalization + +## ModelSerializer API -- cgit v1.2.3 From 2cc4cb24652366c6622af08370a0c04b429aa4b8 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Sat, 31 Jan 2015 08:53:40 +0000 Subject: Fix error text in test. --- docs/topics/3.1-announcement.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/topics/3.1-announcement.md b/docs/topics/3.1-announcement.md index 3eb52f4c..5f4a8d45 100644 --- a/docs/topics/3.1-announcement.md +++ b/docs/topics/3.1-announcement.md @@ -4,7 +4,7 @@ #### Pagination controls in the browsable API. -#### New pagination schemes. +#### New schemes, including cursor pagination. #### Support for header-based pagination. @@ -12,4 +12,6 @@ ## Internationalization +## New fields + ## ModelSerializer API -- cgit v1.2.3 From d015534d530dfdc2bbd7e301ec79fed533d55032 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Tue, 3 Feb 2015 09:15:42 +0000 Subject: Fleshing out 3.1 announcement --- docs/topics/3.1-announcement.md | 69 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) (limited to 'docs') diff --git a/docs/topics/3.1-announcement.md b/docs/topics/3.1-announcement.md index 5f4a8d45..73cccb1c 100644 --- a/docs/topics/3.1-announcement.md +++ b/docs/topics/3.1-announcement.md @@ -1,17 +1,82 @@ # Django REST framework 3.1 +The 3.1 release is an intermediate step in the Kickstarter project releases, and includes a range of new functionality. + ## Pagination +The pagination API has been improved, making it both easier to use, and more powerful. + +#### New pagination schemes. + +Until now, there has only been a single built-in pagination style in REST framework. We now have page, limit/offset and cursor based schemes included by default. + +The cursor based pagination scheme is particularly smart, and is a better approach for clients iterating through large or frequently changing result sets. The scheme supports paging against non-unique indexes, by using both cursor and limit/offset information. Credit to David Cramer for [this blog post](http://cramer.io/2011/03/08/building-cursors-for-the-disqus-api/) on the subject. + #### Pagination controls in the browsable API. -#### New schemes, including cursor pagination. +Paginated results now include controls that render directly in the browsable API. If you're using the page or limit/offset style, then you'll see a page based control displayed in the browsable API. + +**IMAGE** + +The cursor based pagination renders a more simple 'Previous'/'Next' control. + +**IMAGE** #### Support for header-based pagination. +The pagination API was previously only able to alter the pagination style in the body of the response. The API now supports being able to write pagination information in response headers, making it possible to use pagination schemes that use the `Link` or `Content-Range` headers. + +**TODO**: Link to docs. + ## Versioning +We've made it easier to build versioned APIs. Built-in schemes for versioning include both URL based and Accept header based variations. + +When using a URL based scheme, hyperlinked serializers will resolve relationships to the same API version as used on the incoming request. + +**TODO**: Example. + ## Internationalization -## New fields +REST framework now includes a built-in set of translations, and supports internationalized error responses. This allows you to either change the default language, or to allow clients to specify the language via the `Accept-Language` header. + +**TODO**: Example. + +**TODO**: Credit. + +## New field types + +Django 1.8's new `ArrayField`, `HStoreField` and `UUIDField` are now all fully supported. + +This work also means that we now have both `serializers.DictField()`, and `serializers.ListField()` types, allowing you to express and validate a wider set of representations. ## ModelSerializer API + +The serializer redesign in 3.0 did not include any public API for modifying how ModelSerializer classes automatically generate a set of fields from a given mode class. We've now re-introduced an API for this, allowing you to create new ModelSerializer base classes that behave differently, such as using a different default style for relationships. + +**TODO**: Link to docs. + +## Moving packages out of core + +We've now moved a number of packages out of the core of REST framework, and into separately installable packages. If you're currently using these you don't need to worry, you simply need to `pip install` the new packages, and change any import paths. + +We're making this change in order to distribute the maintainance workload, and keep better focus of the core essentials of the framework. + +The change also means we can be more flexible with which external packages we recommend. For example, the excellently maintained [Django OAuth toolkit](https://github.com/evonove/django-oauth-toolkit) is now our recommended option for integrating OAuth support. + +**TODO** Links and package names + +* XML +* YAML +* JSONP +* OAuth + +# What's next? + +The next focus will be on HTML renderings of API output and will include: + +* HTML form rendering of serializers. +* Filtering controls built-in to the browsable API. +* An alternative admin-style interface. + +This will either be made as a single 3.2 release, or split across two separate releases, with the HTML forms and filter controls coming in 3.2, and the admin-style interface coming in a 3.3 release. \ No newline at end of file -- cgit v1.2.3 From 41b213414df57d7e39f1bbf3aaa35a1b033e89a3 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 4 Feb 2015 23:32:25 +0000 Subject: Updating release notes --- docs/topics/3.1-announcement.md | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) (limited to 'docs') diff --git a/docs/topics/3.1-announcement.md b/docs/topics/3.1-announcement.md index 73cccb1c..d5986360 100644 --- a/docs/topics/3.1-announcement.md +++ b/docs/topics/3.1-announcement.md @@ -60,16 +60,30 @@ The serializer redesign in 3.0 did not include any public API for modifying how We've now moved a number of packages out of the core of REST framework, and into separately installable packages. If you're currently using these you don't need to worry, you simply need to `pip install` the new packages, and change any import paths. -We're making this change in order to distribute the maintainance workload, and keep better focus of the core essentials of the framework. +We're making this change in order to help distribute the maintainance workload, and keep better focus of the core essentials of the framework. -The change also means we can be more flexible with which external packages we recommend. For example, the excellently maintained [Django OAuth toolkit](https://github.com/evonove/django-oauth-toolkit) is now our recommended option for integrating OAuth support. +The change also means we can be more flexible with which external packages we recommend. For example, the excellently maintained [Django OAuth toolkit](https://github.com/evonove/django-oauth-toolkit) has now been promoted as our recommended option for integrating OAuth support. -**TODO** Links and package names +The following packages are now moved out of core and should be separately installed: -* XML -* YAML -* JSONP -* OAuth +* OAuth - [djangorestframework-oauth](http://jpadilla.github.io/django-rest-framework-oauth/) +* XML - [djangorestframework-xml](http://jpadilla.github.io/django-rest-framework-xml) +* YAML - [djangorestframework-yaml](http://jpadilla.github.io/django-rest-framework-yaml) +* JSONP - [djangorestframework-jsonp](http://jpadilla.github.io/django-rest-framework-jsonp) + +It's worth reiterating that this change in policy shouldn't mean any work in your codebase other than adding a new requirement and modifying some import paths. For example to install XML rendering, you would now do: + + pip install djangorestframework-xml + +And modify your settings, like so: + + REST_FRAMEWORK = { + 'DEFAULT_RENDERER_CLASSES': [ + 'rest_framework.renderers.JSONRenderer', + 'rest_framework.renderers.BrowsableAPIRenderer', + 'rest_framework_xml.renderers.XMLRenderer' + ] + } # What's next? -- cgit v1.2.3 From 6c63ef13cd9ff8432f15d55a7268f2d402ae38e8 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 6 Feb 2015 00:04:20 +0000 Subject: Drop 2.x announcements --- docs/index.md | 10 +- docs/topics/3.1-announcement.md | 2 +- docs/topics/release-notes.md | 583 +--------------------------------------- 3 files changed, 5 insertions(+), 590 deletions(-) (limited to 'docs') diff --git a/docs/index.md b/docs/index.md index c3a9c2d4..cd243f35 100644 --- a/docs/index.md +++ b/docs/index.md @@ -195,11 +195,8 @@ General guides to using REST framework. * [Third Party Resources][third-party-resources] * [Contributing to REST framework][contributing] * [Project management][project-management] -* [2.0 Announcement][rest-framework-2-announcement] -* [2.2 Announcement][2.2-announcement] -* [2.3 Announcement][2.3-announcement] -* [2.4 Announcement][2.4-announcement] * [3.0 Announcement][3.0-announcement] +* [3.1 Announcement][3.1-announcement] * [Kickstarter Announcement][kickstarter-announcement] * [Release Notes][release-notes] * [Credits][credits] @@ -313,11 +310,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [contributing]: topics/contributing.md [project-management]: topics/project-management.md [third-party-resources]: topics/third-party-resources.md -[rest-framework-2-announcement]: topics/rest-framework-2-announcement.md -[2.2-announcement]: topics/2.2-announcement.md -[2.3-announcement]: topics/2.3-announcement.md -[2.4-announcement]: topics/2.4-announcement.md [3.0-announcement]: topics/3.0-announcement.md +[3.1-announcement]: topics/3.1-announcement.md [kickstarter-announcement]: topics/kickstarter-announcement.md [release-notes]: topics/release-notes.md [credits]: topics/credits.md diff --git a/docs/topics/3.1-announcement.md b/docs/topics/3.1-announcement.md index d5986360..89e99f82 100644 --- a/docs/topics/3.1-announcement.md +++ b/docs/topics/3.1-announcement.md @@ -26,7 +26,7 @@ The cursor based pagination renders a more simple 'Previous'/'Next' control. The pagination API was previously only able to alter the pagination style in the body of the response. The API now supports being able to write pagination information in response headers, making it possible to use pagination schemes that use the `Link` or `Content-Range` headers. -**TODO**: Link to docs. +For more information, see the [custom pagination styles](../api-guide/pagination/#custom-pagination-styles) documentation. ## Versioning diff --git a/docs/topics/release-notes.md b/docs/topics/release-notes.md index e0894d2d..88732df8 100644 --- a/docs/topics/release-notes.md +++ b/docs/topics/release-notes.md @@ -124,598 +124,19 @@ For full details see the [3.0 release announcement](3.0-announcement.md). --- -## 2.4.x series - -### 2.4.4 - -**Date**: [3rd November 2014](https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%222.4.4+Release%22+). - -* **Security fix**: Escape URLs when replacing `format=` query parameter, as used in dropdown on `GET` button in browsable API to allow explicit selection of JSON vs HTML output. -* Maintain ordering of URLs in API root view for `DefaultRouter`. -* Fix `follow=True` in `APIRequestFactory` -* Resolve issue with invalid `read_only=True`, `required=True` fields being automatically generated by `ModelSerializer` in some cases. -* Resolve issue with `OPTIONS` requests returning incorrect information for views using `get_serializer_class` to dynamically determine serializer based on request method. - -### 2.4.3 - -**Date**: [19th September 2014](https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%222.4.3+Release%22+). - -* Support translatable view docstrings being displayed in the browsable API. -* Support [encoded `filename*`][rfc-6266] in raw file uploads with `FileUploadParser`. -* Allow routers to support viewsets that don't include any list routes or that don't include any detail routes. -* Don't render an empty login control in browsable API if `login` view is not included. -* CSRF exemption performed in `.as_view()` to prevent accidental omission if overriding `.dispatch()`. -* Login on browsable API now displays validation errors. -* Bugfix: Fix migration in `authtoken` application. -* Bugfix: Allow selection of integer keys in nested choices. -* Bugfix: Return `None` instead of `'None'` in `CharField` with `allow_none=True`. -* Bugfix: Ensure custom model fields map to equivelent serializer fields more reliably. -* Bugfix: `DjangoFilterBackend` no longer quietly changes queryset ordering. - -### 2.4.2 - -**Date**: [3rd September 2014](https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%222.4.2+Release%22+). - -* Bugfix: Fix broken pagination for 2.4.x series. - -### 2.4.1 - -**Date**: [1st September 2014](https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%222.4.1+Release%22+). - -* Bugfix: Fix broken login template for browsable API. - -### 2.4.0 - -**Date**: [29th August 2014](https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%222.4.0+Release%22+). - -**Django version requirements**: The lowest supported version of Django is now 1.4.2. - -**South version requirements**: This note applies to any users using the optional `authtoken` application, which includes an associated database migration. You must now *either* upgrade your `south` package to version 1.0, *or* instead use the built-in migration support available with Django 1.7. - -* Added compatibility with Django 1.7's database migration support. -* New test runner, using `py.test`. -* Deprecated `.model` view attribute in favor of explicit `.queryset` and `.serializer_class` attributes. The `DEFAULT_MODEL_SERIALIZER_CLASS` setting is also deprecated. -* `@detail_route` and `@list_route` decorators replace `@action` and `@link`. -* Support customizable view name and description functions, using the `VIEW_NAME_FUNCTION` and `VIEW_DESCRIPTION_FUNCTION` settings. -* Added `NUM_PROXIES` setting for smarter client IP identification. -* Added `MAX_PAGINATE_BY` setting and `max_paginate_by` generic view attribute. -* Added `Retry-After` header to throttled responses, as per [RFC 6585](http://tools.ietf.org/html/rfc6585). This should now be used in preference to the custom `X-Trottle-Wait-Seconds` header which will be fully deprecated in 3.0. -* Added `cache` attribute to throttles to allow overriding of default cache. -* Added `lookup_value_regex` attribute to routers, to allow the URL argument matching to be constrainted by the user. -* Added `allow_none` option to `CharField`. -* Support Django's standard `status_code` class attribute on responses. -* More intuitive behavior on the test client, as `client.logout()` now also removes any credentials that have been set. -* Bugfix: `?page_size=0` query parameter now falls back to default page size for view, instead of always turning pagination off. -* Bugfix: Always uppercase `X-Http-Method-Override` methods. -* Bugfix: Copy `filter_backends` list before returning it, in order to prevent view code from mutating the class attribute itself. -* Bugfix: Set the `.action` attribute on viewsets when introspected by `OPTIONS` for testing permissions on the view. -* Bugfix: Ensure `ValueError` raised during deserialization results in a error list rather than a single error. This is now consistent with other validation errors. -* Bugfix: Fix `cache_format` typo on throttle classes, was `"throtte_%(scope)s_%(ident)s"`. Note that this will invalidate existing throttle caches. - ---- - -## 2.3.x series - -### 2.3.14 - -**Date**: 12th June 2014 - -* **Security fix**: Escape request path when it is include as part of the login and logout links in the browsable API. -* `help_text` and `verbose_name` automatically set for related fields on `ModelSerializer`. -* Fix nested serializers linked through a backward foreign key relation. -* Fix bad links for the `BrowsableAPIRenderer` with `YAMLRenderer`. -* Add `UnicodeYAMLRenderer` that extends `YAMLRenderer` with unicode. -* Fix `parse_header` argument convertion. -* Fix mediatype detection under Python 3. -* Web browsable API now offers blank option on dropdown when the field is not required. -* `APIException` representation improved for logging purposes. -* Allow source="*" within nested serializers. -* Better support for custom oauth2 provider backends. -* Fix field validation if it's optional and has no value. -* Add `SEARCH_PARAM` and `ORDERING_PARAM`. -* Fix `APIRequestFactory` to support arguments within the url string for GET. -* Allow three transport modes for access tokens when accessing a protected resource. -* Fix `QueryDict` encoding on request objects. -* Ensure throttle keys do not contain spaces, as those are invalid if using `memcached`. -* Support `blank_display_value` on `ChoiceField`. - -### 2.3.13 - -**Date**: 6th March 2014 - -* Django 1.7 Support. -* Fix `default` argument when used with serializer relation fields. -* Display the media type of the content that is being displayed in the browsable API, rather than 'text/html'. -* Bugfix for `urlize` template failure when URL regex is matched, but value does not `urlparse`. -* Use `urandom` for token generation. -* Only use `Vary: Accept` when more than one renderer exists. - -### 2.3.12 - -**Date**: 15th January 2014 - -* **Security fix**: `OrderingField` now only allows ordering on readable serializer fields, or on fields explicitly specified using `ordering_fields`. This prevents users being able to order by fields that are not visible in the API, and exploiting the ordering of sensitive data such as password hashes. -* Bugfix: `write_only = True` fields now display in the browsable API. - -### 2.3.11 - -**Date**: 14th January 2014 - -* Added `write_only` serializer field argument. -* Added `write_only_fields` option to `ModelSerializer` classes. -* JSON renderer now deals with objects that implement a dict-like interface. -* Fix compatiblity with newer versions of `django-oauth-plus`. -* Bugfix: Refine behavior that calls model manager `all()` across nested serializer relationships, preventing erronous behavior with some non-ORM objects, and preventing unnecessary queryset re-evaluations. -* Bugfix: Allow defaults on BooleanFields to be properly honored when values are not supplied. -* Bugfix: Prevent double-escaping of non-latin1 URL query params when appending `format=json` params. - -### 2.3.10 - -**Date**: 6th December 2013 - -* Add in choices information for ChoiceFields in response to `OPTIONS` requests. -* Added `pre_delete()` and `post_delete()` method hooks. -* Added status code category helper functions. -* Bugfix: Partial updates which erronously set a related field to `None` now correctly fail validation instead of raising an exception. -* Bugfix: Responses without any content no longer include an HTTP `'Content-Type'` header. -* Bugfix: Correctly handle validation errors in PUT-as-create case, responding with 400. - -### 2.3.9 - -**Date**: 15th November 2013 - -* Fix Django 1.6 exception API compatibility issue caused by `ValidationError`. -* Include errors in HTML forms in browsable API. -* Added JSON renderer support for numpy scalars. -* Added `transform_` hooks on serializers for easily modifying field output. -* Added `get_context` hook in `BrowsableAPIRenderer`. -* Allow serializers to be passed `files` but no `data`. -* `HTMLFormRenderer` now renders serializers directly to HTML without needing to create an intermediate form object. -* Added `get_filter_backends` hook. -* Added queryset aggregates to allowed fields in `OrderingFilter`. -* Bugfix: Fix decimal suppoprt with `YAMLRenderer`. -* Bugfix: Fix submission of unicode in browsable API through raw data form. - -### 2.3.8 - -**Date**: 11th September 2013 - -* Added `DjangoObjectPermissions`, and `DjangoObjectPermissionsFilter`. -* Support customizable exception handling, using the `EXCEPTION_HANDLER` setting. -* Support customizable view name and description functions, using the `VIEW_NAME_FUNCTION` and `VIEW_DESCRIPTION_FUNCTION` settings. -* Added `MAX_PAGINATE_BY` setting and `max_paginate_by` generic view attribute. -* Added `cache` attribute to throttles to allow overriding of default cache. -* 'Raw data' tab in browsable API now contains pre-populated data. -* 'Raw data' and 'HTML form' tab preference in browsable API now saved between page views. -* Bugfix: `required=True` argument fixed for boolean serializer fields. -* Bugfix: `client.force_authenticate(None)` should also clear session info if it exists. -* Bugfix: Client sending empty string instead of file now clears `FileField`. -* Bugfix: Empty values on ChoiceFields with `required=False` now consistently return `None`. -* Bugfix: Clients setting `page_size=0` now simply returns the default page size, instead of disabling pagination. [*] - ---- - -[*] Note that the change in `page_size=0` behaviour fixes what is considered to be a bug in how clients can effect the pagination size. However if you were relying on this behavior you will need to add the following mixin to your list views in order to preserve the existing behavior. - - class DisablePaginationMixin(object): - def get_paginate_by(self, queryset=None): - if self.request.QUERY_PARAMS[self.paginate_by_param] == '0': - return None - return super(DisablePaginationMixin, self).get_paginate_by(queryset) - ---- - -### 2.3.7 - -**Date**: 16th August 2013 - -* Added `APITestClient`, `APIRequestFactory` and `APITestCase` etc... -* Refactor `SessionAuthentication` to allow esier override for CSRF exemption. -* Remove 'Hold down "Control" message from help_text' widget messaging when not appropriate. -* Added admin configuration for auth tokens. -* Bugfix: `AnonRateThrottle` fixed to not throttle authenticated users. -* Bugfix: Don't set `X-Throttle-Wait-Seconds` when throttle does not have `wait` value. -* Bugfix: Fixed `PATCH` button title in browsable API. -* Bugfix: Fix issue with OAuth2 provider naive datetimes. - -### 2.3.6 - -**Date**: 27th June 2013 - -* Added `trailing_slash` option to routers. -* Include support for `HttpStreamingResponse`. -* Support wider range of default serializer validation when used with custom model fields. -* UTF-8 Support for browsable API descriptions. -* OAuth2 provider uses timezone aware datetimes when supported. -* Bugfix: Return error correctly when OAuth non-existent consumer occurs. -* Bugfix: Allow `FileUploadParser` to correctly filename if provided as URL kwarg. -* Bugfix: Fix `ScopedRateThrottle`. - -### 2.3.5 - -**Date**: 3rd June 2013 - -* Added `get_url` hook to `HyperlinkedIdentityField`. -* Serializer field `default` argument may be a callable. -* `@action` decorator now accepts a `methods` argument. -* Bugfix: `request.user` should be still be accessible in renderer context if authentication fails. -* Bugfix: The `lookup_field` option on `HyperlinkedIdentityField` should apply by default to the url field on the serializer. -* Bugfix: `HyperlinkedIdentityField` should continue to support `pk_url_kwarg`, `slug_url_kwarg`, `slug_field`, in a pending deprecation state. -* Bugfix: Ensure we always return 404 instead of 500 if a lookup field cannot be converted to the correct lookup type. (Eg non-numeric `AutoInteger` pk lookup) - -### 2.3.4 - -**Date**: 24th May 2013 - -* Serializer fields now support `label` and `help_text`. -* Added `UnicodeJSONRenderer`. -* `OPTIONS` requests now return metadata about fields for `POST` and `PUT` requests. -* Bugfix: `charset` now properly included in `Content-Type` of responses. -* Bugfix: Blank choice now added in browsable API on nullable relationships. -* Bugfix: Many to many relationships with `through` tables are now read-only. -* Bugfix: Serializer fields now respect model field args such as `max_length`. -* Bugfix: SlugField now performs slug validation. -* Bugfix: Lazy-translatable strings now properly serialized. -* Bugfix: Browsable API now supports bootswatch styles properly. -* Bugfix: HyperlinkedIdentityField now uses `lookup_field` kwarg. - -**Note**: Responses now correctly include an appropriate charset on the `Content-Type` header. For example: `application/json; charset=utf-8`. If you have tests that check the content type of responses, you may need to update these accordingly. - -### 2.3.3 - -**Date**: 16th May 2013 - -* Added SearchFilter -* Added OrderingFilter -* Added GenericViewSet -* Bugfix: Multiple `@action` and `@link` methods now allowed on viewsets. -* Bugfix: Fix API Root view issue with DjangoModelPermissions - -### 2.3.2 - -**Date**: 8th May 2013 - -* Bugfix: Fix `TIME_FORMAT`, `DATETIME_FORMAT` and `DATE_FORMAT` settings. -* Bugfix: Fix `DjangoFilterBackend` issue, failing when used on view with queryset attribute. - -### 2.3.1 - -**Date**: 7th May 2013 - -* Bugfix: Fix breadcrumb rendering issue. - -### 2.3.0 - -**Date**: 7th May 2013 - -* ViewSets and Routers. -* ModelSerializers support reverse relations in 'fields' option. -* HyperLinkedModelSerializers support 'id' field in 'fields' option. -* Cleaner generic views. -* Support for multiple filter classes. -* FileUploadParser support for raw file uploads. -* DecimalField support. -* Made Login template easier to restyle. -* Bugfix: Fix issue with depth>1 on ModelSerializer. - -**Note**: See the [2.3 announcement][2.3-announcement] for full details. - ---- - -## 2.2.x series - -### 2.2.7 - -**Date**: 17th April 2013 - -* Loud failure when view does not return a `Response` or `HttpResponse`. -* Bugfix: Fix for Django 1.3 compatibility. -* Bugfix: Allow overridden `get_object()` to work correctly. - -### 2.2.6 - -**Date**: 4th April 2013 - -* OAuth2 authentication no longer requires unnecessary URL parameters in addition to the token. -* URL hyperlinking in browsable API now handles more cases correctly. -* Long HTTP headers in browsable API are broken in multiple lines when possible. -* Bugfix: Fix regression with DjangoFilterBackend not worthing correctly with single object views. -* Bugfix: OAuth should fail hard when invalid token used. -* Bugfix: Fix serializer potentially returning `None` object for models that define `__bool__` or `__len__`. - -### 2.2.5 - -**Date**: 26th March 2013 - -* Serializer support for bulk create and bulk update operations. -* Regression fix: Date and time fields return date/time objects by default. Fixes regressions caused by 2.2.2. See [#743][743] for more details. -* Bugfix: Fix 500 error is OAuth not attempted with OAuthAuthentication class installed. -* `Serializer.save()` now supports arbitrary keyword args which are passed through to the object `.save()` method. Mixins use `force_insert` and `force_update` where appropriate, resulting in one less database query. - -### 2.2.4 - -**Date**: 13th March 2013 - -* OAuth 2 support. -* OAuth 1.0a support. -* Support X-HTTP-Method-Override header. -* Filtering backends are now applied to the querysets for object lookups as well as lists. (Eg you can use a filtering backend to control which objects should 404) -* Deal with error data nicely when deserializing lists of objects. -* Extra override hook to configure `DjangoModelPermissions` for unauthenticated users. -* Bugfix: Fix regression which caused extra database query on paginated list views. -* Bugfix: Fix pk relationship bug for some types of 1-to-1 relations. -* Bugfix: Workaround for Django bug causing case where `Authtoken` could be registered for cascade delete from `User` even if not installed. - -### 2.2.3 - -**Date**: 7th March 2013 - -* Bugfix: Fix None values for for `DateField`, `DateTimeField` and `TimeField`. - -### 2.2.2 - -**Date**: 6th March 2013 - -* Support for custom input and output formats for `DateField`, `DateTimeField` and `TimeField`. -* Cleanup: Request authentication is no longer lazily evaluated, instead authentication is always run, which results in more consistent, obvious behavior. Eg. Supplying bad auth credentials will now always return an error response, even if no permissions are set on the view. -* Bugfix for serializer data being uncacheable with pickle protocol 0. -* Bugfixes for model field validation edge-cases. -* Bugfix for authtoken migration while using a custom user model and south. - -### 2.2.1 - -**Date**: 22nd Feb 2013 - -* Security fix: Use `defusedxml` package to address XML parsing vulnerabilities. -* Raw data tab added to browsable API. (Eg. Allow for JSON input.) -* Added TimeField. -* Serializer fields can be mapped to any method that takes no args, or only takes kwargs which have defaults. -* Unicode support for view names/descriptions in browsable API. -* Bugfix: request.DATA should return an empty `QueryDict` with no data, not `None`. -* Bugfix: Remove unneeded field validation, which caused extra queries. - -**Security note**: Following the [disclosure of security vulnerabilities][defusedxml-announce] in Python's XML parsing libraries, use of the `XMLParser` class now requires the `defusedxml` package to be installed. - -The security vulnerabilities only affect APIs which use the `XMLParser` class, by enabling it in any views, or by having it set in the `DEFAULT_PARSER_CLASSES` setting. Note that the `XMLParser` class is not enabled by default, so this change should affect a minority of users. - -### 2.2.0 - -**Date**: 13th Feb 2013 - -* Python 3 support. -* Added a `post_save()` hook to the generic views. -* Allow serializers to handle dicts as well as objects. -* Deprecate `ManyRelatedField()` syntax in favor of `RelatedField(many=True)` -* Deprecate `null=True` on relations in favor of `required=False`. -* Deprecate `blank=True` on CharFields, just use `required=False`. -* Deprecate optional `obj` argument in permissions checks in favor of `has_object_permission`. -* Deprecate implicit hyperlinked relations behavior. -* Bugfix: Fix broken DjangoModelPermissions. -* Bugfix: Allow serializer output to be cached. -* Bugfix: Fix styling on browsable API login. -* Bugfix: Fix issue with deserializing empty to-many relations. -* Bugfix: Ensure model field validation is still applied for ModelSerializer subclasses with an custom `.restore_object()` method. - -**Note**: See the [2.2 announcement][2.2-announcement] for full details. - ---- - -## 2.1.x series - -### 2.1.17 - -**Date**: 26th Jan 2013 - -* Support proper 401 Unauthorized responses where appropriate, instead of always using 403 Forbidden. -* Support json encoding of timedelta objects. -* `format_suffix_patterns()` now supports `include` style URL patterns. -* Bugfix: Fix issues with custom pagination serializers. -* Bugfix: Nested serializers now accept `source='*'` argument. -* Bugfix: Return proper validation errors when incorrect types supplied for relational fields. -* Bugfix: Support nullable FKs with `SlugRelatedField`. -* Bugfix: Don't call custom validation methods if the field has an error. - -**Note**: If the primary authentication class is `TokenAuthentication` or `BasicAuthentication`, a view will now correctly return 401 responses to unauthenticated access, with an appropriate `WWW-Authenticate` header, instead of 403 responses. - -### 2.1.16 - -**Date**: 14th Jan 2013 - -* Deprecate `django.utils.simplejson` in favor of Python 2.6's built-in json module. -* Bugfix: `auto_now`, `auto_now_add` and other `editable=False` fields now default to read-only. -* Bugfix: PK fields now only default to read-only if they are an AutoField or if `editable=False`. -* Bugfix: Validation errors instead of exceptions when serializers receive incorrect types. -* Bugfix: Validation errors instead of exceptions when related fields receive incorrect types. -* Bugfix: Handle ObjectDoesNotExist exception when serializing null reverse one-to-one - -**Note**: Prior to 2.1.16, The Decimals would render in JSON using floating point if `simplejson` was installed, but otherwise render using string notation. Now that use of `simplejson` has been deprecated, Decimals will consistently render using string notation. See [ticket 582](ticket-582) for more details. - -### 2.1.15 - -**Date**: 3rd Jan 2013 - -* Added `PATCH` support. -* Added `RetrieveUpdateAPIView`. -* Remove unused internal `save_m2m` flag on `ModelSerializer.save()`. -* Tweak behavior of hyperlinked fields with an explicit format suffix. -* Relation changes are now persisted in `.save()` instead of in `.restore_object()`. -* Bugfix: Fix issue with FileField raising exception instead of validation error when files=None. -* Bugfix: Partial updates should not set default values if field is not included. - -### 2.1.14 - -**Date**: 31st Dec 2012 - -* Bugfix: ModelSerializers now include reverse FK fields on creation. -* Bugfix: Model fields with `blank=True` are now `required=False` by default. -* Bugfix: Nested serializers now support nullable relationships. - -**Note**: From 2.1.14 onwards, relational fields move out of the `fields.py` module and into the new `relations.py` module, in order to separate them from regular data type fields, such as `CharField` and `IntegerField`. - -This change will not affect user code, so long as it's following the recommended import style of `from rest_framework import serializers` and referring to fields using the style `serializers.PrimaryKeyRelatedField`. - - -### 2.1.13 - -**Date**: 28th Dec 2012 - -* Support configurable `STATICFILES_STORAGE` storage. -* Bugfix: Related fields now respect the required flag, and may be required=False. - -### 2.1.12 - -**Date**: 21st Dec 2012 - -* Bugfix: Fix bug that could occur using ChoiceField. -* Bugfix: Fix exception in browsable API on DELETE. -* Bugfix: Fix issue where pk was was being set to a string if set by URL kwarg. - -### 2.1.11 - -**Date**: 17th Dec 2012 - -* Bugfix: Fix issue with M2M fields in browsable API. - -### 2.1.10 - -**Date**: 17th Dec 2012 - -* Bugfix: Ensure read-only fields don't have model validation applied. -* Bugfix: Fix hyperlinked fields in paginated results. - -### 2.1.9 - -**Date**: 11th Dec 2012 - -* Bugfix: Fix broken nested serialization. -* Bugfix: Fix `Meta.fields` only working as tuple not as list. -* Bugfix: Edge case if unnecessarily specifying `required=False` on read only field. - -### 2.1.8 - -**Date**: 8th Dec 2012 - -* Fix for creating nullable Foreign Keys with `''` as well as `None`. -* Added `null=` related field option. - -### 2.1.7 - -**Date**: 7th Dec 2012 - -* Serializers now properly support nullable Foreign Keys. -* Serializer validation now includes model field validation, such as uniqueness constraints. -* Support 'true' and 'false' string values for BooleanField. -* Added pickle support for serialized data. -* Support `source='dotted.notation'` style for nested serializers. -* Make `Request.user` settable. -* Bugfix: Fix `RegexField` to work with `BrowsableAPIRenderer`. - -### 2.1.6 - -**Date**: 23rd Nov 2012 - -* Bugfix: Unfix DjangoModelPermissions. (I am a doofus.) - -### 2.1.5 - -**Date**: 23rd Nov 2012 - -* Bugfix: Fix DjangoModelPermissions. - -### 2.1.4 - -**Date**: 22nd Nov 2012 - -* Support for partial updates with serializers. -* Added `RegexField`. -* Added `SerializerMethodField`. -* Serializer performance improvements. -* Added `obtain_token_view` to get tokens when using `TokenAuthentication`. -* Bugfix: Django 1.5 configurable user support for `TokenAuthentication`. - -### 2.1.3 - -**Date**: 16th Nov 2012 - -* Added `FileField` and `ImageField`. For use with `MultiPartParser`. -* Added `URLField` and `SlugField`. -* Support for `read_only_fields` on `ModelSerializer` classes. -* Support for clients overriding the pagination page sizes. Use the `PAGINATE_BY_PARAM` setting or set the `paginate_by_param` attribute on a generic view. -* 201 Responses now return a 'Location' header. -* Bugfix: Serializer fields now respect `max_length`. - -### 2.1.2 - -**Date**: 9th Nov 2012 - -* **Filtering support.** -* Bugfix: Support creation of objects with reverse M2M relations. - -### 2.1.1 - -**Date**: 7th Nov 2012 - -* Support use of HTML exception templates. Eg. `403.html` -* Hyperlinked fields take optional `slug_field`, `slug_url_kwarg` and `pk_url_kwarg` arguments. -* Bugfix: Deal with optional trailing slashes properly when generating breadcrumbs. -* Bugfix: Make textareas same width as other fields in browsable API. -* Private API change: `.get_serializer` now uses same `instance` and `data` ordering as serializer initialization. - -### 2.1.0 - -**Date**: 5th Nov 2012 - -* **Serializer `instance` and `data` keyword args have their position swapped.** -* `queryset` argument is now optional on writable model fields. -* Hyperlinked related fields optionally take `slug_field` and `slug_url_kwarg` arguments. -* Support Django's cache framework. -* Minor field improvements. (Don't stringify dicts, more robust many-pk fields.) -* Bugfix: Support choice field in Browsable API. -* Bugfix: Related fields with `read_only=True` do not require a `queryset` argument. - -**API-incompatible changes**: Please read [this thread][2.1.0-notes] regarding the `instance` and `data` keyword args before updating to 2.1.0. - ---- - -## 2.0.x series - -### 2.0.2 - -**Date**: 2nd Nov 2012 - -* Fix issues with pk related fields in the browsable API. - -### 2.0.1 - -**Date**: 1st Nov 2012 - -* Add support for relational fields in the browsable API. -* Added SlugRelatedField and ManySlugRelatedField. -* If PUT creates an instance return '201 Created', instead of '200 OK'. - -### 2.0.0 - -**Date**: 30th Oct 2012 - -* **Fix all of the things.** (Well, almost.) -* For more information please see the [2.0 announcement][announcement]. - -For older release notes, [please see the GitHub repo](old-release-notes). +For older release notes, [please see the version 2.x documentation](old-release-notes). [cite]: http://www.catb.org/~esr/writings/cathedral-bazaar/cathedral-bazaar/ar01s04.html [deprecation-policy]: #deprecation-policy [django-deprecation-policy]: https://docs.djangoproject.com/en/dev/internals/release-process/#internal-release-deprecation-policy [defusedxml-announce]: http://blog.python.org/2013/02/announcing-defusedxml-fixes-for-xml.html -[2.2-announcement]: 2.2-announcement.md -[2.3-announcement]: 2.3-announcement.md [743]: https://github.com/tomchristie/django-rest-framework/pull/743 [staticfiles14]: https://docs.djangoproject.com/en/1.4/howto/static-files/#with-a-template-tag [staticfiles13]: https://docs.djangoproject.com/en/1.3/howto/static-files/#with-a-template-tag [2.1.0-notes]: https://groups.google.com/d/topic/django-rest-framework/Vv2M0CMY9bg/discussion -[announcement]: rest-framework-2-announcement.md [ticket-582]: https://github.com/tomchristie/django-rest-framework/issues/582 [rfc-6266]: http://tools.ietf.org/html/rfc6266#section-4.3 -[old-release-notes]: https://github.com/tomchristie/django-rest-framework/blob/2.4.4/docs/topics/release-notes.md#04x-series +[old-release-notes]: http://tomchristie.github.io/rest-framework-2-docs/topics/release-notes#24x-series [3.0.1-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.0.1+Release%22 [3.0.2-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.0.2+Release%22 -- cgit v1.2.3 From 09488ad4da321f5f15d6e3df348869b8f2116b4a Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 6 Feb 2015 00:25:03 +0000 Subject: Link to ModelSerializer API --- docs/topics/3.1-announcement.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/topics/3.1-announcement.md b/docs/topics/3.1-announcement.md index 89e99f82..d0975f5b 100644 --- a/docs/topics/3.1-announcement.md +++ b/docs/topics/3.1-announcement.md @@ -54,7 +54,7 @@ This work also means that we now have both `serializers.DictField()`, and `seria The serializer redesign in 3.0 did not include any public API for modifying how ModelSerializer classes automatically generate a set of fields from a given mode class. We've now re-introduced an API for this, allowing you to create new ModelSerializer base classes that behave differently, such as using a different default style for relationships. -**TODO**: Link to docs. +For more information, see the documentation on [customizing field mappings](../api-guide/serializers/#customizing-field-mappings) for ModelSerializer classes. ## Moving packages out of core -- cgit v1.2.3 From 53716f61527266159c285b903da98ec432e52564 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 6 Feb 2015 11:37:29 +0000 Subject: Internationalization docs --- docs/index.md | 2 - docs/topics/3.1-announcement.md | 77 ++++++- docs/topics/credits.md | 404 ------------------------------------ docs/topics/internationalization.md | 41 ++++ 4 files changed, 113 insertions(+), 411 deletions(-) delete mode 100644 docs/topics/credits.md (limited to 'docs') diff --git a/docs/index.md b/docs/index.md index cd243f35..23781419 100644 --- a/docs/index.md +++ b/docs/index.md @@ -199,7 +199,6 @@ General guides to using REST framework. * [3.1 Announcement][3.1-announcement] * [Kickstarter Announcement][kickstarter-announcement] * [Release Notes][release-notes] -* [Credits][credits] ## Development @@ -314,7 +313,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [3.1-announcement]: topics/3.1-announcement.md [kickstarter-announcement]: topics/kickstarter-announcement.md [release-notes]: topics/release-notes.md -[credits]: topics/credits.md [tox]: http://testrun.org/tox/latest/ diff --git a/docs/topics/3.1-announcement.md b/docs/topics/3.1-announcement.md index d0975f5b..080ef1d8 100644 --- a/docs/topics/3.1-announcement.md +++ b/docs/topics/3.1-announcement.md @@ -10,7 +10,7 @@ The pagination API has been improved, making it both easier to use, and more pow Until now, there has only been a single built-in pagination style in REST framework. We now have page, limit/offset and cursor based schemes included by default. -The cursor based pagination scheme is particularly smart, and is a better approach for clients iterating through large or frequently changing result sets. The scheme supports paging against non-unique indexes, by using both cursor and limit/offset information. Credit to David Cramer for [this blog post](http://cramer.io/2011/03/08/building-cursors-for-the-disqus-api/) on the subject. +The cursor based pagination scheme is particularly smart, and is a better approach for clients iterating through large or frequently changing result sets. The scheme supports paging against non-unique indexes, by using both cursor and limit/offset information. It also allows for both forward and reverse cursor pagination. Much credit goes to David Cramer for [this blog post](http://cramer.io/2011/03/08/building-cursors-for-the-disqus-api/) on the subject. #### Pagination controls in the browsable API. @@ -34,15 +34,74 @@ We've made it easier to build versioned APIs. Built-in schemes for versioning in When using a URL based scheme, hyperlinked serializers will resolve relationships to the same API version as used on the incoming request. -**TODO**: Example. +For example, when using `NamespaceVersioning`, and the following hyperlinked serializer: + + class AccountsSerializer(serializer.HyperlinkedModelSerializer): + class Meta: + model = Accounts + fields = ('account_name', 'users') + +The output representation would match the version used on the incoming request. Like so: + + GET http://example.org/v2/accounts/10 # Version 'v2' + + { + "account_name": "europa", + "users": [ + "http://example.org/v2/users/12", # Version 'v2' + "http://example.org/v2/users/54", + "http://example.org/v2/users/87" + ] + } ## Internationalization REST framework now includes a built-in set of translations, and supports internationalized error responses. This allows you to either change the default language, or to allow clients to specify the language via the `Accept-Language` header. -**TODO**: Example. +You can change the default language by using the standard Django `LANGUAGE_CODE` setting: + + LANGUAGE_CODE = "es-es" + +You can turn on per-request language requests by adding `LocalMiddleware` to your `MIDDLEWARE_CLASSES` setting: + + MIDDLEWARE_CLASSES = [ + ... + 'django.middleware.locale.LocaleMiddleware' + ] + +When per-request internationalization is enabled, client requests will respect the `Accept-Language` header where possible. For example, let's make a request for an unsupported media type: + +**Request** + + GET /api/users HTTP/1.1 + Accept: application/xml + Accept-Language: es-es + Host: example.org + +**Response** -**TODO**: Credit. + HTTP/1.0 406 NOT ACCEPTABLE + + { + "detail": "No se ha podido satisfacer la solicitud de cabecera de Accept." + } + +Note that the structure of the error responses is still the same. We still have a `details` key in the response. If needed you can modify this behavior too, by using a [custom exception handler][custom-exception-handler]. + +We include built-in translations both for standard exception cases, and for serializer validation errors. + +The full list of supported languages can be found on our [Transifex project page](https://www.transifex.com/projects/p/django-rest-framework/). + +If you only wish to support a subset of the supported languages, use Django's standard `LANGUAGES` setting: + + LANGUAGES = [ + ('de', _('German')), + ('en', _('English')), + ] + +For more details, see the [internationalization documentation](internationalization.md). + +Many thanks to [Craig Blaszczyk](https://github.com/jakul) for helping push this through. ## New field types @@ -50,6 +109,10 @@ Django 1.8's new `ArrayField`, `HStoreField` and `UUIDField` are now all fully s This work also means that we now have both `serializers.DictField()`, and `serializers.ListField()` types, allowing you to express and validate a wider set of representations. +If you're building a new 1.8 project, then you should probably consider using `UUIDField` as the primary keys for all your models. This style will work automatically with hyperlinked serializers, returning URLs in the following style: + + http://example.org/api/purchases/9b1a433f-e90d-4948-848b-300fdc26365d + ## ModelSerializer API The serializer redesign in 3.0 did not include any public API for modifying how ModelSerializer classes automatically generate a set of fields from a given mode class. We've now re-introduced an API for this, allowing you to create new ModelSerializer base classes that behave differently, such as using a different default style for relationships. @@ -85,6 +148,8 @@ And modify your settings, like so: ] } +Thanks go to the latest member of our maintenance team, [José Padilla](https://github.com/jpadilla/), for handling this work and taking on ownership of these packages. + # What's next? The next focus will be on HTML renderings of API output and will include: @@ -93,4 +158,6 @@ The next focus will be on HTML renderings of API output and will include: * Filtering controls built-in to the browsable API. * An alternative admin-style interface. -This will either be made as a single 3.2 release, or split across two separate releases, with the HTML forms and filter controls coming in 3.2, and the admin-style interface coming in a 3.3 release. \ No newline at end of file +This will either be made as a single 3.2 release, or split across two separate releases, with the HTML forms and filter controls coming in 3.2, and the admin-style interface coming in a 3.3 release. + +[custom-exception-handler]: ../api-guide/exceptions.md#custom-exception-handling diff --git a/docs/topics/credits.md b/docs/topics/credits.md deleted file mode 100644 index 5f0dc752..00000000 --- a/docs/topics/credits.md +++ /dev/null @@ -1,404 +0,0 @@ -# Credits - -The following people have helped make REST framework great. - -* Tom Christie - [tomchristie] -* Marko Tibold - [markotibold] -* Paul Miller - [paulmillr] -* Sébastien Piquemal - [sebpiq] -* Carmen Wick - [cwick] -* Alex Ehlke - [aehlke] -* Alen Mujezinovic - [flashingpumpkin] -* Carles Barrobés - [txels] -* Michael Fötsch - [mfoetsch] -* David Larlet - [david] -* Andrew Straw - [astraw] -* Zeth - [zeth] -* Fernando Zunino - [fzunino] -* Jens Alm - [ulmus] -* Craig Blaszczyk - [jakul] -* Garcia Solero - [garciasolero] -* Tom Drummond - [devioustree] -* Danilo Bargen - [dbrgn] -* Andrew McCloud - [amccloud] -* Thomas Steinacher - [thomasst] -* Meurig Freeman - [meurig] -* Anthony Nemitz - [anemitz] -* Ewoud Kohl van Wijngaarden - [ekohl] -* Michael Ding - [yandy] -* Mjumbe Poe - [mjumbewu] -* Natim - [natim] -* Sebastian Żurek - [sebzur] -* Benoit C - [dzen] -* Chris Pickett - [bunchesofdonald] -* Ben Timby - [btimby] -* Michele Lazzeri - [michelelazzeri-nextage] -* Camille Harang - [mammique] -* Paul Oswald - [poswald] -* Sean C. Farley - [scfarley] -* Daniel Izquierdo - [izquierdo] -* Can Yavuz - [tschan] -* Shawn Lewis - [shawnlewis] -* Alec Perkins - [alecperkins] -* Michael Barrett - [phobologic] -* Mathieu Dhondt - [laundromat] -* Johan Charpentier - [cyberj] -* Jamie Matthews - [j4mie] -* Mattbo - [mattbo] -* Max Hurl - [maximilianhurl] -* Tomi Pajunen - [eofs] -* Rob Dobson - [rdobson] -* Daniel Vaca Araujo - [diviei] -* Madis Väin - [madisvain] -* Stephan Groß - [minddust] -* Pavel Savchenko - [asfaltboy] -* Otto Yiu - [ottoyiu] -* Jacob Magnusson - [jmagnusson] -* Osiloke Harold Emoekpere - [osiloke] -* Michael Shepanski - [mjs7231] -* Toni Michel - [tonimichel] -* Ben Konrath - [benkonrath] -* Marc Aymerich - [glic3rinu] -* Ludwig Kraatz - [ludwigkraatz] -* Rob Romano - [robromano] -* Eugene Mechanism - [mechanism] -* Jonas Liljestrand - [jonlil] -* Justin Davis - [irrelative] -* Dustin Bachrach - [dbachrach] -* Mark Shirley - [maspwr] -* Olivier Aubert - [oaubert] -* Yuri Prezument - [yprez] -* Fabian Buechler - [fabianbuechler] -* Mark Hughes - [mhsparks] -* Michael van de Waeter - [mvdwaeter] -* Reinout van Rees - [reinout] -* Michael Richards - [justanotherbody] -* Ben Roberts - [roberts81] -* Venkata Subramanian Mahalingam - [annacoder] -* George Kappel - [gkappel] -* Colin Murtaugh - [cmurtaugh] -* Simon Pantzare - [pilt] -* Szymon Teżewski - [sunscrapers] -* Joel Marcotte - [joual] -* Trey Hunner - [treyhunner] -* Roman Akinfold - [akinfold] -* Toran Billups - [toranb] -* Sébastien Béal - [sebastibe] -* Andrew Hankinson - [ahankinson] -* Juan Riaza - [juanriaza] -* Michael Mior - [michaelmior] -* Marc Tamlyn - [mjtamlyn] -* Richard Wackerbarth - [wackerbarth] -* Johannes Spielmann - [shezi] -* James Cleveland - [radiosilence] -* Steve Gregory - [steve-gregory] -* Federico Capoano - [nemesisdesign] -* Bruno Renié - [brutasse] -* Kevin Stone - [kevinastone] -* Guglielmo Celata - [guglielmo] -* Mike Tums - [mktums] -* Michael Elovskikh - [wronglink] -* Michał Jaworski - [swistakm] -* Andrea de Marco - [z4r] -* Fernando Rocha - [fernandogrd] -* Xavier Ordoquy - [xordoquy] -* Adam Wentz - [floppya] -* Andreas Pelme - [pelme] -* Ryan Detzel - [ryanrdetzel] -* Omer Katz - [thedrow] -* Wiliam Souza - [waa] -* Jonas Braun - [iekadou] -* Ian Dash - [bitmonkey] -* Bouke Haarsma - [bouke] -* Pierre Dulac - [dulaccc] -* Dave Kuhn - [kuhnza] -* Sitong Peng - [stoneg] -* Victor Shih - [vshih] -* Atle Frenvik Sveen - [atlefren] -* J Paul Reed - [preed] -* Matt Majewski - [forgingdestiny] -* Jerome Chen - [chenjyw] -* Andrew Hughes - [eyepulp] -* Daniel Hepper - [dhepper] -* Hamish Campbell - [hamishcampbell] -* Marlon Bailey - [avinash240] -* James Summerfield - [jsummerfield] -* Andy Freeland - [rouge8] -* Craig de Stigter - [craigds] -* Pablo Recio - [pyriku] -* Brian Zambrano - [brianz] -* Òscar Vilaplana - [grimborg] -* Ryan Kaskel - [ryankask] -* Andy McKay - [andymckay] -* Matteo Suppo - [matteosuppo] -* Karol Majta - [lolek09] -* David Jones - [commonorgarden] -* Andrew Tarzwell - [atarzwell] -* Michal Dvořák - [mikee2185] -* Markus Törnqvist - [mjtorn] -* Pascal Borreli - [pborreli] -* Alex Burgel - [aburgel] -* David Medina - [copitux] -* Areski Belaid - [areski] -* Ethan Freman - [mindlace] -* David Sanders - [davesque] -* Philip Douglas - [freakydug] -* Igor Kalat - [trwired] -* Rudolf Olah - [omouse] -* Gertjan Oude Lohuis - [gertjanol] -* Matthias Jacob - [cyroxx] -* Pavel Zinovkin - [pzinovkin] -* Will Kahn-Greene - [willkg] -* Kevin Brown - [kevin-brown] -* Rodrigo Martell - [coderigo] -* James Rutherford - [jimr] -* Ricky Rosario - [rlr] -* Veronica Lynn - [kolvia] -* Dan Stephenson - [etos] -* Martin Clement - [martync] -* Jeremy Satterfield - [jsatt] -* Christopher Paolini - [chrispaolini] -* Filipe A Ximenes - [filipeximenes] -* Ramiro Morales - [ramiro] -* Krzysztof Jurewicz - [krzysiekj] -* Eric Buehl - [ericbuehl] -* Kristian Øllegaard - [kristianoellegaard] -* Alexander Akhmetov - [alexander-akhmetov] -* Andrey Antukh - [niwibe] -* Mathieu Pillard - [diox] -* Edmond Wong - [edmondwong] -* Ben Reilly - [bwreilly] -* Tai Lee - [mrmachine] -* Markus Kaiserswerth - [mkai] -* Henry Clifford - [hcliff] -* Thomas Badaud - [badale] -* Colin Huang - [tamakisquare] -* Ross McFarland - [ross] -* Jacek Bzdak - [jbzdak] -* Alexander Lukanin - [alexanderlukanin13] -* Yamila Moreno - [yamila-moreno] -* Rob Hudson - [robhudson] -* Alex Good - [alexjg] -* Ian Foote - [ian-foote] -* Chuck Harmston - [chuckharmston] -* Philip Forget - [philipforget] -* Artem Mezhenin - [amezhenin] - -Many thanks to everyone who's contributed to the project. - -## Additional thanks - -The documentation is built with [Bootstrap] and [Markdown]. - -Project hosting is with [GitHub]. - -Continuous integration testing is managed with [Travis CI][travis-ci]. - -The [live sandbox][sandbox] is hosted on [Heroku]. - -Various inspiration taken from the [Rails], [Piston], [Tastypie], [Dagny] and [django-viewsets] projects. - -Development of REST framework 2.0 was sponsored by [DabApps]. - -## Contact - -For usage questions please see the [REST framework discussion group][group]. - -You can also contact [@_tomchristie][twitter] directly on twitter. - -[twitter]: http://twitter.com/_tomchristie -[bootstrap]: http://twitter.github.com/bootstrap/ -[markdown]: http://daringfireball.net/projects/markdown/ -[github]: https://github.com/tomchristie/django-rest-framework -[travis-ci]: https://secure.travis-ci.org/tomchristie/django-rest-framework -[rails]: http://rubyonrails.org/ -[piston]: https://bitbucket.org/jespern/django-piston -[tastypie]: https://github.com/toastdriven/django-tastypie -[dagny]: https://github.com/zacharyvoase/dagny -[django-viewsets]: https://github.com/BertrandBordage/django-viewsets -[dabapps]: http://lab.dabapps.com -[sandbox]: http://restframework.herokuapp.com/ -[heroku]: http://www.heroku.com/ -[group]: https://groups.google.com/forum/?fromgroups#!forum/django-rest-framework - -[tomchristie]: https://github.com/tomchristie -[markotibold]: https://github.com/markotibold -[paulmillr]: https://github.com/paulmillr -[sebpiq]: https://github.com/sebpiq -[cwick]: https://github.com/cwick -[aehlke]: https://github.com/aehlke -[flashingpumpkin]: https://github.com/flashingpumpkin -[txels]: https://github.com/txels -[mfoetsch]: https://github.com/mfoetsch -[david]: https://github.com/david -[astraw]: https://github.com/astraw -[zeth]: https://github.com/zeth -[fzunino]: https://github.com/fzunino -[ulmus]: https://github.com/ulmus -[jakul]: https://github.com/jakul -[garciasolero]: https://github.com/garciasolero -[devioustree]: https://github.com/devioustree -[dbrgn]: https://github.com/dbrgn -[amccloud]: https://github.com/amccloud -[thomasst]: https://github.com/thomasst -[meurig]: https://github.com/meurig -[anemitz]: https://github.com/anemitz -[ekohl]: https://github.com/ekohl -[yandy]: https://github.com/yandy -[mjumbewu]: https://github.com/mjumbewu -[natim]: https://github.com/natim -[sebzur]: https://github.com/sebzur -[dzen]: https://github.com/dzen -[bunchesofdonald]: https://github.com/bunchesofdonald -[btimby]: https://github.com/btimby -[michelelazzeri-nextage]: https://github.com/michelelazzeri-nextage -[mammique]: https://github.com/mammique -[poswald]: https://github.com/poswald -[scfarley]: https://github.com/scfarley -[izquierdo]: https://github.com/izquierdo -[tschan]: https://github.com/tschan -[shawnlewis]: https://github.com/shawnlewis -[alecperkins]: https://github.com/alecperkins -[phobologic]: https://github.com/phobologic -[laundromat]: https://github.com/laundromat -[cyberj]: https://github.com/cyberj -[j4mie]: https://github.com/j4mie -[mattbo]: https://github.com/mattbo -[maximilianhurl]: https://github.com/maximilianhurl -[eofs]: https://github.com/eofs -[rdobson]: https://github.com/rdobson -[diviei]: https://github.com/diviei -[madisvain]: https://github.com/madisvain -[minddust]: https://github.com/minddust -[asfaltboy]: https://github.com/asfaltboy -[ottoyiu]: https://github.com/OttoYiu -[jmagnusson]: https://github.com/jmagnusson -[osiloke]: https://github.com/osiloke -[mjs7231]: https://github.com/mjs7231 -[tonimichel]: https://github.com/tonimichel -[benkonrath]: https://github.com/benkonrath -[glic3rinu]: https://github.com/glic3rinu -[ludwigkraatz]: https://github.com/ludwigkraatz -[robromano]: https://github.com/robromano -[mechanism]: https://github.com/mechanism -[jonlil]: https://github.com/jonlil -[irrelative]: https://github.com/irrelative -[dbachrach]: https://github.com/dbachrach -[maspwr]: https://github.com/maspwr -[oaubert]: https://github.com/oaubert -[yprez]: https://github.com/yprez -[fabianbuechler]: https://github.com/fabianbuechler -[mhsparks]: https://github.com/mhsparks -[mvdwaeter]: https://github.com/mvdwaeter -[reinout]: https://github.com/reinout -[justanotherbody]: https://github.com/justanotherbody -[roberts81]: https://github.com/roberts81 -[annacoder]: https://github.com/annacoder -[gkappel]: https://github.com/gkappel -[cmurtaugh]: https://github.com/cmurtaugh -[pilt]: https://github.com/pilt -[sunscrapers]: https://github.com/sunscrapers -[joual]: https://github.com/joual -[treyhunner]: https://github.com/treyhunner -[akinfold]: https://github.com/akinfold -[toranb]: https://github.com/toranb -[sebastibe]: https://github.com/sebastibe -[ahankinson]: https://github.com/ahankinson -[juanriaza]: https://github.com/juanriaza -[michaelmior]: https://github.com/michaelmior -[mjtamlyn]: https://github.com/mjtamlyn -[wackerbarth]: https://github.com/wackerbarth -[shezi]: https://github.com/shezi -[radiosilence]: https://github.com/radiosilence -[steve-gregory]: https://github.com/steve-gregory -[nemesisdesign]: https://github.com/nemesisdesign -[brutasse]: https://github.com/brutasse -[kevinastone]: https://github.com/kevinastone -[guglielmo]: https://github.com/guglielmo -[mktums]: https://github.com/mktums -[wronglink]: https://github.com/wronglink -[swistakm]: https://github.com/swistakm -[z4r]: https://github.com/z4r -[fernandogrd]: https://github.com/fernandogrd -[xordoquy]: https://github.com/xordoquy -[floppya]: https://github.com/floppya -[pelme]: https://github.com/pelme -[ryanrdetzel]: https://github.com/ryanrdetzel -[thedrow]: https://github.com/thedrow -[waa]: https://github.com/wiliamsouza -[iekadou]: https://github.com/iekadou -[bitmonkey]: https://github.com/bitmonkey -[bouke]: https://github.com/bouke -[dulaccc]: https://github.com/dulaccc -[kuhnza]: https://github.com/kuhnza -[stoneg]: https://github.com/stoneg -[vshih]: https://github.com/vshih -[atlefren]: https://github.com/atlefren -[preed]: https://github.com/preed -[forgingdestiny]: https://github.com/forgingdestiny -[chenjyw]: https://github.com/chenjyw -[eyepulp]: https://github.com/eyepulp -[dhepper]: https://github.com/dhepper -[hamishcampbell]: https://github.com/hamishcampbell -[avinash240]: https://github.com/avinash240 -[jsummerfield]: https://github.com/jsummerfield -[rouge8]: https://github.com/rouge8 -[craigds]: https://github.com/craigds -[pyriku]: https://github.com/pyriku -[brianz]: https://github.com/brianz -[grimborg]: https://github.com/grimborg -[ryankask]: https://github.com/ryankask -[andymckay]: https://github.com/andymckay -[matteosuppo]: https://github.com/matteosuppo -[lolek09]: https://github.com/lolek09 -[commonorgarden]: https://github.com/commonorgarden -[atarzwell]: https://github.com/atarzwell -[mikee2185]: https://github.com/mikee2185 -[mjtorn]: https://github.com/mjtorn -[pborreli]: https://github.com/pborreli -[aburgel]: https://github.com/aburgel -[copitux]: https://github.com/copitux -[areski]: https://github.com/areski -[mindlace]: https://github.com/mindlace -[davesque]: https://github.com/davesque -[freakydug]: https://github.com/freakydug -[trwired]: https://github.com/trwired -[omouse]: https://github.com/omouse -[gertjanol]: https://github.com/gertjanol -[cyroxx]: https://github.com/cyroxx -[pzinovkin]: https://github.com/pzinovkin -[coderigo]: https://github.com/coderigo -[willkg]: https://github.com/willkg -[kevin-brown]: https://github.com/kevin-brown -[jimr]: https://github.com/jimr -[rlr]: https://github.com/rlr -[kolvia]: https://github.com/kolvia -[etos]: https://github.com/etos -[martync]: https://github.com/martync -[jsatt]: https://github.com/jsatt -[chrispaolini]: https://github.com/chrispaolini -[filipeximenes]: https://github.com/filipeximenes -[ramiro]: https://github.com/ramiro -[krzysiekj]: https://github.com/krzysiekj -[ericbuehl]: https://github.com/ericbuehl -[kristianoellegaard]: https://github.com/kristianoellegaard -[alexander-akhmetov]: https://github.com/alexander-akhmetov -[niwibe]: https://github.com/niwibe -[diox]: https://github.com/diox -[edmondwong]: https://github.com/edmondwong -[bwreilly]: https://github.com/bwreilly -[mrmachine]: https://github.com/mrmachine -[mkai]: https://github.com/mkai -[hcliff]: https://github.com/hcliff -[badale]: https://github.com/badale -[tamakisquare]: https://github.com/tamakisquare -[ross]: https://github.com/ross -[jbzdak]: https://github.com/jbzdak -[alexanderlukanin13]: https://github.com/alexanderlukanin13 -[yamila-moreno]: https://github.com/yamila-moreno -[robhudson]: https://github.com/robhudson -[alexjg]: https://github.com/alexjg -[ian-foote]: https://github.com/ian-foote -[chuckharmston]: https://github.com/chuckharmston -[philipforget]: https://github.com/philipforget -[amezhenin]: https://github.com/amezhenin diff --git a/docs/topics/internationalization.md b/docs/topics/internationalization.md index fdde6c43..3968e23d 100644 --- a/docs/topics/internationalization.md +++ b/docs/topics/internationalization.md @@ -11,12 +11,53 @@ Doing so will allow you to: * Select a language other than English as the default, using the standard `LANGUAGE_CODE` Django setting. * Allow clients to choose a language themselves, using the `LocaleMiddleware` included with Django. A typical usage for API clients would be to include an `Accept-Language` request header. +## Enabling internationalized APIs + +You can change the default language by using the standard Django `LANGUAGE_CODE` setting: + + LANGUAGE_CODE = "es-es" + +You can turn on per-request language requests by adding `LocalMiddleware` to your `MIDDLEWARE_CLASSES` setting: + + MIDDLEWARE_CLASSES = [ + ... + 'django.middleware.locale.LocaleMiddleware' + ] + +When per-request internationalization is enabled, client requests will respect the `Accept-Language` header where possible. For example, let's make a request for an unsupported media type: + +**Request** + + GET /api/users HTTP/1.1 + Accept: application/xml + Accept-Language: es-es + Host: example.org + +**Response** + + HTTP/1.0 406 NOT ACCEPTABLE + + {"detail": "No se ha podido satisfacer la solicitud de cabecera de Accept."} + +REST framework includes these built-in translations both for standard exception cases, and for serializer validation errors. + Note that the translations only apply to the error strings themselves. The format of error messages, and the keys of field names will remain the same. An example `400 Bad Request` response body might look like this: {"detail": {"username": ["Esse campo deve ser unico."]}} If you want to use different string for parts of the response such as `detail` and `non_field_errors` then you can modify this behavior by using a [custom exception handler][custom-exception-handler]. +#### Specifying the set of supported languages. + +By default all available languages will be supported. + +If you only wish to support a subset of the available languages, use Django's standard `LANGUAGES` setting: + + LANGUAGES = [ + ('de', _('German')), + ('en', _('English')), + ] + ## Adding new translations REST framework translations are managed online using [Transifex][transifex-project]. You can use the Transifex service to add new translation languages. The maintenance team will then ensure that these translation strings are included in the REST framework package. -- cgit v1.2.3 From 1d4956f61615ed32f52b2f92bb8ae31b09279a34 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 6 Feb 2015 13:08:04 +0000 Subject: Pagination images --- docs/img/cursor-pagination.png | Bin 0 -> 12221 bytes docs/img/pages-pagination.png | Bin 0 -> 10229 bytes docs/topics/3.1-announcement.md | 33 ++++++++++++++++++++++++++++----- 3 files changed, 28 insertions(+), 5 deletions(-) create mode 100644 docs/img/cursor-pagination.png create mode 100644 docs/img/pages-pagination.png (limited to 'docs') diff --git a/docs/img/cursor-pagination.png b/docs/img/cursor-pagination.png new file mode 100644 index 00000000..1c9c99b6 Binary files /dev/null and b/docs/img/cursor-pagination.png differ diff --git a/docs/img/pages-pagination.png b/docs/img/pages-pagination.png new file mode 100644 index 00000000..4ce1a09a Binary files /dev/null and b/docs/img/pages-pagination.png differ diff --git a/docs/topics/3.1-announcement.md b/docs/topics/3.1-announcement.md index 080ef1d8..fb4fa083 100644 --- a/docs/topics/3.1-announcement.md +++ b/docs/topics/3.1-announcement.md @@ -2,6 +2,17 @@ The 3.1 release is an intermediate step in the Kickstarter project releases, and includes a range of new functionality. +Some highlights include: + +* A super-smart cursor pagination scheme. +* An improved pagination API, supporting header or in-body pagination styles. +* Pagination controls rendering in the browsable API. +* Better support for API versioning. +* Built-in internalization support. +* Support for Django 1.8's `HStoreField` and `ArrayField`. + +--- + ## Pagination The pagination API has been improved, making it both easier to use, and more powerful. @@ -14,13 +25,13 @@ The cursor based pagination scheme is particularly smart, and is a better approa #### Pagination controls in the browsable API. -Paginated results now include controls that render directly in the browsable API. If you're using the page or limit/offset style, then you'll see a page based control displayed in the browsable API. +Paginated results now include controls that render directly in the browsable API. If you're using the page or limit/offset style, then you'll see a page based control displayed in the browsable API: -**IMAGE** +![page number based pagination](../img/pages-pagination.png ) -The cursor based pagination renders a more simple 'Previous'/'Next' control. +The cursor based pagination renders a more simple style of control: -**IMAGE** +![cursor based pagination](../img/cursor-pagination.png ) #### Support for header-based pagination. @@ -28,6 +39,8 @@ The pagination API was previously only able to alter the pagination style in the For more information, see the [custom pagination styles](../api-guide/pagination/#custom-pagination-styles) documentation. +--- + ## Versioning We've made it easier to build versioned APIs. Built-in schemes for versioning include both URL based and Accept header based variations. @@ -54,6 +67,8 @@ The output representation would match the version used on the incoming request. ] } +--- + ## Internationalization REST framework now includes a built-in set of translations, and supports internationalized error responses. This allows you to either change the default language, or to allow clients to specify the language via the `Accept-Language` header. @@ -103,6 +118,8 @@ For more details, see the [internationalization documentation](internationalizat Many thanks to [Craig Blaszczyk](https://github.com/jakul) for helping push this through. +--- + ## New field types Django 1.8's new `ArrayField`, `HStoreField` and `UUIDField` are now all fully supported. @@ -113,12 +130,16 @@ If you're building a new 1.8 project, then you should probably consider using `U http://example.org/api/purchases/9b1a433f-e90d-4948-848b-300fdc26365d +--- + ## ModelSerializer API The serializer redesign in 3.0 did not include any public API for modifying how ModelSerializer classes automatically generate a set of fields from a given mode class. We've now re-introduced an API for this, allowing you to create new ModelSerializer base classes that behave differently, such as using a different default style for relationships. For more information, see the documentation on [customizing field mappings](../api-guide/serializers/#customizing-field-mappings) for ModelSerializer classes. +--- + ## Moving packages out of core We've now moved a number of packages out of the core of REST framework, and into separately installable packages. If you're currently using these you don't need to worry, you simply need to `pip install` the new packages, and change any import paths. @@ -150,7 +171,9 @@ And modify your settings, like so: Thanks go to the latest member of our maintenance team, [José Padilla](https://github.com/jpadilla/), for handling this work and taking on ownership of these packages. -# What's next? +--- + +## What's next? The next focus will be on HTML renderings of API output and will include: -- cgit v1.2.3 From 1f996128458570a909d13f15c3d739fb12111984 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 6 Feb 2015 13:21:35 +0000 Subject: Upgrade pending deprecations to deprecations --- docs/topics/3.1-announcement.md | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'docs') diff --git a/docs/topics/3.1-announcement.md b/docs/topics/3.1-announcement.md index fb4fa083..7242a032 100644 --- a/docs/topics/3.1-announcement.md +++ b/docs/topics/3.1-announcement.md @@ -173,6 +173,16 @@ Thanks go to the latest member of our maintenance team, [José Padilla](https:// --- +## Deprecations + +The `request.DATA`, `request.FILES` and `request.QUERY_PARAMS` attributes move from pending deprecation, to deprecated. Use `request.data` and `request.query_params` instead, as discussed in the 3.0 release notes. + +The ModelSerializer Meta options for `write_only_fields`, `view_name` and `lookup_field` are also moved from pending deprecation, to deprecated. Use `extra_kwargs` instead, as discussed in the 3.0 release notes. + +All these attributes and options will still work in 3.1, but their usage will raise a warning. They will be fully removed in 3.2. + +--- + ## What's next? The next focus will be on HTML renderings of API output and will include: -- cgit v1.2.3