aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/api-guide/pagination.md23
-rw-r--r--docs/topics/3.1-announcement.md10
-rw-r--r--docs/topics/release-notes.md5
3 files changed, 27 insertions, 11 deletions
diff --git a/docs/api-guide/pagination.md b/docs/api-guide/pagination.md
index 13bd57ae..bc65267f 100644
--- a/docs/api-guide/pagination.md
+++ b/docs/api-guide/pagination.md
@@ -51,7 +51,8 @@ You can then apply your new style to a view using the `.pagination_class` attrib
Or apply the style globally, using the `DEFAULT_PAGINATION_CLASS` settings key. For example:
REST_FRAMEWORK = {
- 'DEFAULT_PAGINATION_CLASS': 'apps.core.pagination.StandardResultsSetPagination' }
+ 'DEFAULT_PAGINATION_CLASS': 'apps.core.pagination.StandardResultsSetPagination'
+ }
---
@@ -158,18 +159,23 @@ Cursor based pagination requires that there is a unique, unchanging ordering of
Cursor based pagination is more complex than other schemes. It also requires that the result set presents a fixed ordering, and does not allow the client to arbitrarily index into the result set. However it does provide the following benefits:
-* Provides a consistent pagination view. When used properly `CursorPagination` ensures that the client will never see the same item twice when paging through records.
+* Provides a consistent pagination view. When used properly `CursorPagination` ensures that the client will never see the same item twice when paging through records, even when new items are being inserted by other clients during the pagination process.
* Supports usage with very large datasets. With extremely large datasets pagination using offset-based pagination styles may become inefficient or unusable. Cursor based pagination schemes instead have fixed-time properties, and do not slow down as the dataset size increases.
#### Details and limitations
-This implementation of cursor pagination uses a smart "position plus offset" style that allows it to properly support not-strictly-unique values as the ordering.
+Proper use of cursor based pagination a little attention to detail. You'll need to think about what ordering you want the scheme to be applied against. The default is to order by `"-created"`. This assumes that **there must be a 'created' timestamp field** on the model instances, and will present a "timeline" style paginated view, with the most recently added items first.
-It should be noted that using non-unique values the ordering does introduce the possibility of paging artifacts, where pagination consistency is no longer 100% guaranteed.
+You can modify the ordering by overriding the `'ordering'` attribute on the pagination class, or by using the `OrderingFilter` filter class together with `CursorPagination`. When used with `OrderingFilter` you should strongly consider restricting the fields that the user may order by.
-**TODO**: Notes on `None`.
+Proper usage of cursor pagination should have an ordering field that satisfies the following:
-The implementation also supports both forward and reverse pagination, which is often not supported in other implementations.
+* Should be an unchanging value, such as a timestamp, slug, or other field that is only set once, on creation.
+* Should be unique, or nearly unique. Millisecond precision timestamps are a good example. This implementation of cursor pagination uses a smart "position plus offset" style that allows it to properly support not-strictly-unique values as the ordering.
+* Should be a non-nullable value that can be coerced to a string.
+* The field should have a database index.
+
+Using an ordering field that does not satisfy these constraints will generally still work, but you'll be loosing some of the benefits of cursor pagination.
For more technical details on the implementation we use for cursor pagination, the ["Building cursors for the Disqus API"][disqus-cursor-api] blog post gives a good overview of the basic approach.
@@ -192,7 +198,7 @@ To set these attributes you should override the `CursorPagination` class, and th
* `page_size` = A numeric value indicating the page size. If set, this overrides the `DEFAULT_PAGE_SIZE` setting. Defaults to the same value as the `DEFAULT_PAGE_SIZE` settings key.
* `cursor_query_param` = A string value indicating the name of the "cursor" query parameter. Defaults to `'cursor'`.
-* `ordering` = This should be a string, or list of strings, indicating the field against which the cursor based pagination will be applied. For example: `ordering = 'created'`. Any filters on the view which define a `get_ordering` will override this attribute. Defaults to `None`.
+* `ordering` = This should be a string, or list of strings, indicating the field against which the cursor based pagination will be applied. For example: `ordering = 'slug'`. Defaults to `-created`. This value may also be overridden by using `OrderingFilter` on the view.
* `template` = The name of a template to use when rendering pagination controls in the browsable API. May be overridden to modify the rendering style, or set to `None` to disable HTML pagination controls completely. Defaults to `"rest_framework/pagination/previous_and_next.html"`.
---
@@ -236,7 +242,8 @@ Let's modify the built-in `PageNumberPagination` style, so that instead of inclu
class LinkHeaderPagination(pagination.PageNumberPagination):
def get_paginated_response(self, data):
- next_url = self.get_next_link() previous_url = self.get_previous_link()
+ next_url = self.get_next_link()
+ previous_url = self.get_previous_link()
if next_url is not None and previous_url is not None:
link = '<{next_url}; rel="next">, <{previous_url}; rel="prev">'
diff --git a/docs/topics/3.1-announcement.md b/docs/topics/3.1-announcement.md
index ecbc9a38..6eb3681f 100644
--- a/docs/topics/3.1-announcement.md
+++ b/docs/topics/3.1-announcement.md
@@ -52,7 +52,7 @@ For more information, see the [custom pagination styles](../api-guide/pagination
## Versioning
-We've made it easier to build versioned APIs. Built-in schemes for versioning include both URL based and Accept header based variations.
+We've made it [easier to build versioned APIs][versioning]. 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.
@@ -80,7 +80,7 @@ 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.
+REST framework now includes a built-in set of translations, and [supports internationalized error responses][internationalization]. This allows you to either change the default language, or to allow clients to specify the language via the `Accept-Language` header.
You can change the default language by using the standard Django `LANGUAGE_CODE` setting:
@@ -145,7 +145,7 @@ If you're building a new 1.8 project, then you should probably consider using `U
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.
+For more information, see the documentation on [customizing field mappings][customizing-field-mappings] for ModelSerializer classes.
---
@@ -203,3 +203,7 @@ The next focus will be on HTML renderings of API output and will include:
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
+[pagination]: ../api-guide/pagination.md
+[versioning]: ../api-guide/versioning.md
+[internationalization]: internationalization.md
+[customizing-field-mappings]: ../api-guide/serializers.md/#customizing-field-mappings
diff --git a/docs/topics/release-notes.md b/docs/topics/release-notes.md
index 51eb45c3..35592feb 100644
--- a/docs/topics/release-notes.md
+++ b/docs/topics/release-notes.md
@@ -40,6 +40,11 @@ You can determine your currently installed version using `pip freeze`:
## 3.0.x series
+### 3.1.0
+
+**Date**: [5th March 2015][3.1.0-milestone].
+
+For full details see the [3.1 release announcement](3.1-announcement.md).
### 3.0.5