From 294d957361c78cdafcef60f915738ed0e533327c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20Gro=C3=9F?= Date: Wed, 31 Jul 2013 20:14:49 +0200 Subject: [PATCH 01/23] Add drf-any-permission docs entry --- docs/api-guide/permissions.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/api-guide/permissions.md b/docs/api-guide/permissions.md index 2c0a055c8..57636bc6f 100644 --- a/docs/api-guide/permissions.md +++ b/docs/api-guide/permissions.md @@ -188,6 +188,16 @@ Note that the generic views will check the appropriate object level permissions, Also note that the generic views will only check the object-level permissions for views that retrieve a single model instance. If you require object-level filtering of list views, you'll need to filter the queryset separately. See the [filtering documentation][filtering] for more details. +--- + +# Third party packages + +The following third party packages are also available. + +## DRF Any Permissions + +The [DRF Any Permissions][drf-any-permissions] packages provides a different permission behavior in contrast to the REST framework. Only one of the given permissions have to be true in order to get access to the view. + [cite]: https://developer.apple.com/library/mac/#documentation/security/Conceptual/AuthenticationAndAuthorizationGuide/Authorization/Authorization.html [authentication]: authentication.md [throttling]: throttling.md @@ -197,3 +207,4 @@ Also note that the generic views will only check the object-level permissions fo [django-oauth2-provider]: https://github.com/caffeinehit/django-oauth2-provider [2.2-announcement]: ../topics/2.2-announcement.md [filtering]: filtering.md +[drf-any-permissions]: https://github.com/kevin-brown/drf-any-permissions From e61210399154723f342ab9295c938bf72c8da7a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20Gro=C3=9F?= Date: Wed, 31 Jul 2013 20:25:28 +0200 Subject: [PATCH 02/23] Fix typo --- docs/api-guide/permissions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api-guide/permissions.md b/docs/api-guide/permissions.md index 57636bc6f..5597886d2 100644 --- a/docs/api-guide/permissions.md +++ b/docs/api-guide/permissions.md @@ -196,7 +196,7 @@ The following third party packages are also available. ## DRF Any Permissions -The [DRF Any Permissions][drf-any-permissions] packages provides a different permission behavior in contrast to the REST framework. Only one of the given permissions have to be true in order to get access to the view. +The [DRF Any Permissions][drf-any-permissions] packages provides a different permission behavior in contrast to the REST framework. Only one of the given permissions has to be true in order to get access to the view. [cite]: https://developer.apple.com/library/mac/#documentation/security/Conceptual/AuthenticationAndAuthorizationGuide/Authorization/Authorization.html [authentication]: authentication.md From 3802442c89a722da7e48210d315856b5993fcdbe Mon Sep 17 00:00:00 2001 From: Ricky Rosario Date: Thu, 1 Aug 2013 17:02:16 -0400 Subject: [PATCH 03/23] Add missing comma to generic view example. --- docs/api-guide/generic-views.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api-guide/generic-views.md b/docs/api-guide/generic-views.md index 67853ed01..32a4feef4 100755 --- a/docs/api-guide/generic-views.md +++ b/docs/api-guide/generic-views.md @@ -40,7 +40,7 @@ For more complex cases you might also want to override various methods on the vi For very simple cases you might want to pass through any class attributes using the `.as_view()` method. For example, your URLconf might include something the following entry. - url(r'^/users/', ListCreateAPIView.as_view(model=User) name='user-list') + url(r'^/users/', ListCreateAPIView.as_view(model=User), name='user-list') --- From e4144b5b674cc8849c248727a09b82b82d1a01c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20Gro=C3=9F?= Date: Fri, 2 Aug 2013 08:59:18 +0200 Subject: [PATCH 04/23] Add @rlr for #1022 thanks! --- docs/topics/credits.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/topics/credits.md b/docs/topics/credits.md index 4cc7f34b8..d1fa3681d 100644 --- a/docs/topics/credits.md +++ b/docs/topics/credits.md @@ -152,6 +152,7 @@ The following people have helped make REST framework great. * Kevin Brown - [kevin-brown] * Rodrigo Martell - [coderigo] * James Rutherford - [jimr] +* ricky rosario - [rlr] Many thanks to everyone who's contributed to the project. @@ -340,3 +341,4 @@ You can also contact [@_tomchristie][twitter] directly on twitter. [willkg]: https://github.com/willkg [kevin-brown]: https://github.com/kevin-brown [jimr]: https://github.com/jimr +[rlr]: https://github.com/rlr From 4ff1dc6a11ec9e1fd897cf2fdb74d57be7420515 Mon Sep 17 00:00:00 2001 From: James Summerfield Date: Sat, 3 Aug 2013 10:23:39 +0100 Subject: [PATCH 05/23] Fixing typos in routers.md --- docs/api-guide/routers.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/api-guide/routers.md b/docs/api-guide/routers.md index 865829057..7f53f109d 100644 --- a/docs/api-guide/routers.md +++ b/docs/api-guide/routers.md @@ -38,7 +38,7 @@ The example above would generate the following URL patterns: ### Extra link and actions Any methods on the viewset decorated with `@link` or `@action` will also be routed. -For example, a given method like this on the `UserViewSet` class: +For example, given a method like this on the `UserViewSet` class: @action(permission_classes=[IsAdminOrIsSelf]) def set_password(self, request, pk=None): @@ -66,7 +66,7 @@ This router includes routes for the standard set of `list`, `create`, `retrieve` POST@action decorated method -By default the URLs created by `SimpleRouter` are appending with a trailing slash. +By default the URLs created by `SimpleRouter` are appended with a trailing slash. This behavior can be modified by setting the `trailing_slash` argument to `False` when instantiating the router. For example: router = SimpleRouter(trailing_slash=False) @@ -90,7 +90,7 @@ This router is similar to `SimpleRouter` as above, but additionally includes a d POST@action decorated method -As with `SimpleRouter` the trailing slashs on the URL routes can be removed by setting the `trailing_slash` argument to `False` when instantiating the router. +As with `SimpleRouter` the trailing slashes on the URL routes can be removed by setting the `trailing_slash` argument to `False` when instantiating the router. router = DefaultRouter(trailing_slash=False) @@ -139,7 +139,7 @@ The `SimpleRouter` class provides another example of setting the `.routes` attri ## Advanced custom routers -If you want to provide totally custom behavior, you can override `BaseRouter` and override the `get_urls(self)` method. The method should insect the registered viewsets and return a list of URL patterns. The registered prefix, viewset and basename tuples may be inspected by accessing the `self.registry` attribute. +If you want to provide totally custom behavior, you can override `BaseRouter` and override the `get_urls(self)` method. The method should inspect the registered viewsets and return a list of URL patterns. The registered prefix, viewset and basename tuples may be inspected by accessing the `self.registry` attribute. You may also want to override the `get_default_base_name(self, viewset)` method, or else always explicitly set the `base_name` argument when registering your viewsets with the router. From 4d8d2340be4de905af3488dc721c7b94b1371ef0 Mon Sep 17 00:00:00 2001 From: Veronica Lynn Date: Wed, 7 Aug 2013 14:00:06 -0400 Subject: [PATCH 06/23] Fixed typos in a bunch of docs --- docs/api-guide/permissions.md | 2 +- docs/api-guide/relations.md | 8 ++++---- docs/api-guide/renderers.md | 2 +- docs/api-guide/responses.md | 4 ++-- docs/api-guide/reverse.md | 2 +- docs/api-guide/routers.md | 2 +- docs/api-guide/serializers.md | 6 +++--- docs/api-guide/settings.md | 4 ++-- docs/api-guide/testing.md | 2 +- docs/api-guide/views.md | 2 +- docs/topics/2.2-announcement.md | 6 +++--- docs/topics/2.3-announcement.md | 12 ++++++------ docs/topics/documenting-your-api.md | 8 ++++---- docs/tutorial/1-serialization.md | 2 +- docs/tutorial/3-class-based-views.md | 2 +- 15 files changed, 32 insertions(+), 32 deletions(-) diff --git a/docs/api-guide/permissions.md b/docs/api-guide/permissions.md index 5597886d2..096ef3691 100644 --- a/docs/api-guide/permissions.md +++ b/docs/api-guide/permissions.md @@ -147,7 +147,7 @@ If you need to test if a request is a read operation or a write operation, you s **Note**: In versions 2.0 and 2.1, the signature for the permission checks always included an optional `obj` parameter, like so: `.has_permission(self, request, view, obj=None)`. The method would be called twice, first for the global permission checks, with no object supplied, and second for the object-level check when required. -As of version 2.2 this signature has now been replaced with two separate method calls, which is more explict and obvious. The old style signature continues to work, but it's use will result in a `PendingDeprecationWarning`, which is silent by default. In 2.3 this will be escalated to a `DeprecationWarning`, and in 2.4 the old-style signature will be removed. +As of version 2.2 this signature has now been replaced with two separate method calls, which is more explicit and obvious. The old style signature continues to work, but its use will result in a `PendingDeprecationWarning`, which is silent by default. In 2.3 this will be escalated to a `DeprecationWarning`, and in 2.4 the old-style signature will be removed. For more details see the [2.2 release announcement][2.2-announcement]. diff --git a/docs/api-guide/relations.md b/docs/api-guide/relations.md index 50c9bc546..829a3c548 100644 --- a/docs/api-guide/relations.md +++ b/docs/api-guide/relations.md @@ -39,7 +39,7 @@ In order to explain the various types of relational fields, we'll use a couple o ## RelatedField -`RelatedField` may be used to represent the target of the relationship using it's `__unicode__` method. +`RelatedField` may be used to represent the target of the relationship using its `__unicode__` method. For example, the following serializer. @@ -71,7 +71,7 @@ This field is read only. ## PrimaryKeyRelatedField -`PrimaryKeyRelatedField` may be used to represent the target of the relationship using it's primary key. +`PrimaryKeyRelatedField` may be used to represent the target of the relationship using its primary key. For example, the following serializer: @@ -252,7 +252,7 @@ If you want to implement a read-write relational field, you must also implement ## Example -For, example, we could define a relational field, to serialize a track to a custom string representation, using it's ordering, title, and duration. +For, example, we could define a relational field, to serialize a track to a custom string representation, using its ordering, title, and duration. import time @@ -386,7 +386,7 @@ For more information see [the Django documentation on generic relations][generic By default, relational fields that target a ``ManyToManyField`` with a ``through`` model specified are set to read-only. -If you exlicitly specify a relational field pointing to a +If you explicitly specify a relational field pointing to a ``ManyToManyField`` with a through model, be sure to set ``read_only`` to ``True``. diff --git a/docs/api-guide/renderers.md b/docs/api-guide/renderers.md index b434efe9a..bb3d20159 100644 --- a/docs/api-guide/renderers.md +++ b/docs/api-guide/renderers.md @@ -241,7 +241,7 @@ This renderer is used for rendering HTML multipart form data. **It is not suita To implement a custom renderer, you should override `BaseRenderer`, set the `.media_type` and `.format` properties, and implement the `.render(self, data, media_type=None, renderer_context=None)` method. -The method should return a bytestring, which wil be used as the body of the HTTP response. +The method should return a bytestring, which will be used as the body of the HTTP response. The arguments passed to the `.render()` method are: diff --git a/docs/api-guide/responses.md b/docs/api-guide/responses.md index 399b7c23f..5a42aa923 100644 --- a/docs/api-guide/responses.md +++ b/docs/api-guide/responses.md @@ -24,7 +24,7 @@ Unless you want to heavily customize REST framework for some reason, you should Unlike regular `HttpResponse` objects, you do not instantiate `Response` objects with rendered content. Instead you pass in unrendered data, which may consist of any Python primitives. -The renderers used by the `Response` class cannot natively handle complex datatypes such as Django model instances, so you need to serialize the data into primative datatypes before creating the `Response` object. +The renderers used by the `Response` class cannot natively handle complex datatypes such as Django model instances, so you need to serialize the data into primitive datatypes before creating the `Response` object. You can use REST framework's `Serializer` classes to perform this data serialization, or use your own custom serialization. @@ -54,7 +54,7 @@ The rendered content of the response. The `.render()` method must have been cal ## .template_name -The `template_name`, if supplied. Only required if `HTMLRenderer` or some other custom template renderer is the accepted renderer for the reponse. +The `template_name`, if supplied. Only required if `HTMLRenderer` or some other custom template renderer is the accepted renderer for the response. ## .accepted_renderer diff --git a/docs/api-guide/reverse.md b/docs/api-guide/reverse.md index 19930dc3f..942623666 100644 --- a/docs/api-guide/reverse.md +++ b/docs/api-guide/reverse.md @@ -17,7 +17,7 @@ The advantages of doing so are: REST framework provides two utility functions to make it more simple to return absolute URIs from your Web API. -There's no requirement for you to use them, but if you do then the self-describing API will be able to automatically hyperlink it's output for you, which makes browsing the API much easier. +There's no requirement for you to use them, but if you do then the self-describing API will be able to automatically hyperlink its output for you, which makes browsing the API much easier. ## reverse diff --git a/docs/api-guide/routers.md b/docs/api-guide/routers.md index 7f53f109d..072a2e79a 100644 --- a/docs/api-guide/routers.md +++ b/docs/api-guide/routers.md @@ -96,7 +96,7 @@ As with `SimpleRouter` the trailing slashes on the URL routes can be removed by # Custom Routers -Implementing a custom router isn't something you'd need to do very often, but it can be useful if you have specific requirements about how the your URLs for your API are strutured. Doing so allows you to encapsulate the URL structure in a reusable way that ensures you don't have to write your URL patterns explicitly for each new view. +Implementing a custom router isn't something you'd need to do very often, but it can be useful if you have specific requirements about how the your URLs for your API are structured. Doing so allows you to encapsulate the URL structure in a reusable way that ensures you don't have to write your URL patterns explicitly for each new view. The simplest way to implement a custom router is to subclass one of the existing router classes. The `.routes` attribute is used to template the URL patterns that will be mapped to each viewset. The `.routes` attribute is a list of `Route` named tuples. diff --git a/docs/api-guide/serializers.md b/docs/api-guide/serializers.md index a1f0853e3..bbc8d019d 100644 --- a/docs/api-guide/serializers.md +++ b/docs/api-guide/serializers.md @@ -403,7 +403,7 @@ You can change the field that is used for object lookups by setting the `lookup_ Not that the `lookup_field` will be used as the default on *all* hyperlinked fields, including both the URL identity, and any hyperlinked relationships. -For more specfic requirements such as specifying a different lookup for each field, you'll want to set the fields on the serializer explicitly. For example: +For more specific requirements such as specifying a different lookup for each field, you'll want to set the fields on the serializer explicitly. For example: class AccountSerializer(serializers.HyperlinkedModelSerializer): url = serializers.HyperlinkedIdentityField( @@ -429,7 +429,7 @@ You can create customized subclasses of `ModelSerializer` or `HyperlinkedModelSe Doing so should be considered advanced usage, and will only be needed if you have some particular serializer requirements that you often need to repeat. -## Dynamically modifiying fields +## Dynamically modifying fields Once a serializer has been initialized, the dictionary of fields that are set on the serializer may be accessed using the `.fields` attribute. Accessing and modifying this attribute allows you to dynamically modify the serializer. @@ -449,7 +449,7 @@ For example, if you wanted to be able to set which fields should be used by a se # Don't pass the 'fields' arg up to the superclass fields = kwargs.pop('fields', None) - # Instatiate the superclass normally + # Instantiate the superclass normally super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs) if fields: diff --git a/docs/api-guide/settings.md b/docs/api-guide/settings.md index 7b114983d..0be0eb24a 100644 --- a/docs/api-guide/settings.md +++ b/docs/api-guide/settings.md @@ -28,7 +28,7 @@ you should use the `api_settings` object. For example. print api_settings.DEFAULT_AUTHENTICATION_CLASSES -The `api_settings` object will check for any user-defined settings, and otherwise fallback to the default values. Any setting that uses string import paths to refer to a class will automatically import and return the referenced class, instead of the string literal. +The `api_settings` object will check for any user-defined settings, and otherwise fall back to the default values. Any setting that uses string import paths to refer to a class will automatically import and return the referenced class, instead of the string literal. --- @@ -165,7 +165,7 @@ Default: `'multipart'` The renderer classes that are supported when building test requests. -The format of any of these renderer classes may be used when contructing a test request, for example: `client.post('/users', {'username': 'jamie'}, format='json')` +The format of any of these renderer classes may be used when constructing a test request, for example: `client.post('/users', {'username': 'jamie'}, format='json')` Default: diff --git a/docs/api-guide/testing.md b/docs/api-guide/testing.md index 40b077633..92f8d54aa 100644 --- a/docs/api-guide/testing.md +++ b/docs/api-guide/testing.md @@ -34,7 +34,7 @@ To support a wider set of request formats, or change the default format, [see th #### Explicitly encoding the request body -If you need to explictly encode the request body, you can do so by setting the `content_type` flag. For example: +If you need to explicitly encode the request body, you can do so by setting the `content_type` flag. For example: request = factory.post('/notes/', json.dumps({'title': 'new idea'}), content_type='application/json') diff --git a/docs/api-guide/views.md b/docs/api-guide/views.md index 683222d16..15581e098 100644 --- a/docs/api-guide/views.md +++ b/docs/api-guide/views.md @@ -110,7 +110,7 @@ You won't typically need to override this method. ### .finalize_response(self, request, response, \*args, **kwargs) -Ensures that any `Response` object returned from the handler method will be rendered into the correct content type, as determined by the content negotation. +Ensures that any `Response` object returned from the handler method will be rendered into the correct content type, as determined by the content negotiation. You won't typically need to override this method. diff --git a/docs/topics/2.2-announcement.md b/docs/topics/2.2-announcement.md index 02cac1295..7d2760499 100644 --- a/docs/topics/2.2-announcement.md +++ b/docs/topics/2.2-announcement.md @@ -136,15 +136,15 @@ Now becomes: def has_object_permission(self, request, view, obj): return obj.owner == request.user -If you're overriding the `BasePermission` class, the old-style signature will continue to function, and will correctly handle both global and object-level permissions checks, but it's use will raise a `PendingDeprecationWarning`. +If you're overriding the `BasePermission` class, the old-style signature will continue to function, and will correctly handle both global and object-level permissions checks, but its use will raise a `PendingDeprecationWarning`. Note also that the usage of the internal APIs for permission checking on the `View` class has been cleaned up slightly, and is now documented and subject to the deprecation policy in all future versions. ### More explicit hyperlink relations behavior -When using a serializer with a `HyperlinkedRelatedField` or `HyperlinkedIdentityField`, the hyperlinks would previously use absolute URLs if the serializer context included a `'request'` key, and fallback to using relative URLs otherwise. This could lead to non-obvious behavior, as it might not be clear why some serializers generated absolute URLs, and others do not. +When using a serializer with a `HyperlinkedRelatedField` or `HyperlinkedIdentityField`, the hyperlinks would previously use absolute URLs if the serializer context included a `'request'` key, and fall back to using relative URLs otherwise. This could lead to non-obvious behavior, as it might not be clear why some serializers generated absolute URLs, and others do not. -From version 2.2 onwards, serializers with hyperlinked relationships *always* require a `'request'` key to be supplied in the context dictionary. The implicit behavior will continue to function, but it's use will raise a `PendingDeprecationWarning`. +From version 2.2 onwards, serializers with hyperlinked relationships *always* require a `'request'` key to be supplied in the context dictionary. The implicit behavior will continue to function, but its use will raise a `PendingDeprecationWarning`. [xordoquy]: https://github.com/xordoquy [django-python-3]: https://docs.djangoproject.com/en/dev/faq/install/#can-i-use-django-with-python-3 diff --git a/docs/topics/2.3-announcement.md b/docs/topics/2.3-announcement.md index 9fdebcd90..ba4351459 100644 --- a/docs/topics/2.3-announcement.md +++ b/docs/topics/2.3-announcement.md @@ -131,7 +131,7 @@ The `get_object` and `get_paginate_by` methods no longer take an optional querys Using an optional queryset with these methods continues to be supported, but will raise a `PendingDeprecationWarning`. -The `paginate_queryset` method no longer takes a `page_size` argument, or returns a four-tuple of pagination information. Instead it simply takes a queryset argument, and either returns a `page` object with an appropraite page size, or returns `None`, if pagination is not configured for the view. +The `paginate_queryset` method no longer takes a `page_size` argument, or returns a four-tuple of pagination information. Instead it simply takes a queryset argument, and either returns a `page` object with an appropriate page size, or returns `None`, if pagination is not configured for the view. Using the `page_size` argument is still supported and will trigger the old-style return type, but will raise a `PendingDeprecationWarning`. @@ -195,13 +195,13 @@ Usage of the old-style attributes continues to be supported, but will raise a `P 2.3 introduces a `DecimalField` serializer field, which returns `Decimal` instances. -For most cases APIs using model fields will behave as previously, however if you are using a custom renderer, not provided by REST framework, then you may now need to add support for rendering `Decimal` instances to your renderer implmentation. +For most cases APIs using model fields will behave as previously, however if you are using a custom renderer, not provided by REST framework, then you may now need to add support for rendering `Decimal` instances to your renderer implementation. ## ModelSerializers and reverse relationships The support for adding reverse relationships to the `fields` option on a `ModelSerializer` class means that the `get_related_field` and `get_nested_field` method signatures have now changed. -In the unlikely event that you're providing a custom serializer class, and implementing these methods you should note the new call signature for both methods is now `(self, model_field, related_model, to_many)`. For revese relationships `model_field` will be `None`. +In the unlikely event that you're providing a custom serializer class, and implementing these methods you should note the new call signature for both methods is now `(self, model_field, related_model, to_many)`. For reverse relationships `model_field` will be `None`. The old-style signature will continue to function but will raise a `PendingDeprecationWarning`. @@ -219,7 +219,7 @@ Note that the relevant methods have always been private APIs, and the docstrings ## More explicit style -The usage of `model` attribute in generic Views is still supported, but it's usage is generally being discouraged throughout the documentation, in favour of the setting the more explict `queryset` and `serializer_class` attributes. +The usage of `model` attribute in generic Views is still supported, but it's usage is generally being discouraged throughout the documentation, in favour of the setting the more explicit `queryset` and `serializer_class` attributes. For example, the following is now the recommended style for using generic views: @@ -227,7 +227,7 @@ For example, the following is now the recommended style for using generic views: queryset = MyModel.objects.all() serializer_class = MyModelSerializer -Using an explict `queryset` and `serializer_class` attributes makes the functioning of the view more clear than using the shortcut `model` attribute. +Using an explicit `queryset` and `serializer_class` attributes makes the functioning of the view more clear than using the shortcut `model` attribute. It also makes the usage of the `get_queryset()` or `get_serializer_class()` methods more obvious. @@ -246,7 +246,7 @@ It also makes the usage of the `get_queryset()` or `get_serializer_class()` meth ## Django 1.3 support -The 2.3.x release series will be the last series to provide compatiblity with Django 1.3. +The 2.3.x release series will be the last series to provide compatibility with Django 1.3. ## Version 2.2 API changes diff --git a/docs/topics/documenting-your-api.md b/docs/topics/documenting-your-api.md index 7ee538f55..6291c924a 100644 --- a/docs/topics/documenting-your-api.md +++ b/docs/topics/documenting-your-api.md @@ -16,7 +16,7 @@ The most common way to document Web APIs today is to produce documentation that Marc Gibbons' [Django REST Swagger][django-rest-swagger] integrates REST framework with the [Swagger][swagger] API documentation tool. The package produces well presented API documentation, and includes interactive tools for testing API endpoints. -The pacakge is fully documented, well supported, and comes highly recommended. +The package is fully documented, well supported, and comes highly recommended. Django REST Swagger supports REST framework versions 2.3 and above. @@ -42,7 +42,7 @@ There are various other online tools and services for providing API documentatio ## Self describing APIs -The browsable API that REST framwork provides makes it possible for your API to be entirely self describing. The documentation for each API endpoint can be provided simply by visiting the URL in your browser. +The browsable API that REST framework provides makes it possible for your API to be entirely self describing. The documentation for each API endpoint can be provided simply by visiting the URL in your browser. ![Screenshot - Self describing API][image-self-describing-api] @@ -93,11 +93,11 @@ You can modify the response behavior to `OPTIONS` requests by overriding the `me ## The hypermedia approach -To be fully RESTful an API should present it's available actions as hypermedia controls in the responses that it sends. +To be fully RESTful an API should present its available actions as hypermedia controls in the responses that it sends. In this approach, rather than documenting the available API endpoints up front, the description instead concentrates on the *media types* that are used. The available actions take may be taken on any given URL are not strictly fixed, but are instead made available by the presence of link and form controls in the returned document. -To implement a hypermedia API you'll need to decide on an appropriate media type for the API, and implement a custom renderer and parser for that media type. The [REST, Hypermedia & HATEOAS][hypermedia-docs] section of the documention includes pointers to background reading, as well as links to various hypermedia formats. +To implement a hypermedia API you'll need to decide on an appropriate media type for the API, and implement a custom renderer and parser for that media type. The [REST, Hypermedia & HATEOAS][hypermedia-docs] section of the documentation includes pointers to background reading, as well as links to various hypermedia formats. [cite]: http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven [django-rest-swagger]: https://github.com/marcgibbons/django-rest-swagger diff --git a/docs/tutorial/1-serialization.md b/docs/tutorial/1-serialization.md index 2b214d6a6..22d29285b 100644 --- a/docs/tutorial/1-serialization.md +++ b/docs/tutorial/1-serialization.md @@ -236,7 +236,7 @@ Edit the `snippet/views.py` file, and add the following. class JSONResponse(HttpResponse): """ - An HttpResponse that renders it's content into JSON. + An HttpResponse that renders its content into JSON. """ def __init__(self, data, **kwargs): content = JSONRenderer().render(data) diff --git a/docs/tutorial/3-class-based-views.md b/docs/tutorial/3-class-based-views.md index c1b3d8f23..9fc424fee 100644 --- a/docs/tutorial/3-class-based-views.md +++ b/docs/tutorial/3-class-based-views.md @@ -81,7 +81,7 @@ Okay, we're done. If you run the development server everything should be workin One of the big wins of using class based views is that it allows us to easily compose reusable bits of behaviour. -The create/retrieve/update/delete operations that we've been using so far are going to be pretty simliar for any model-backed API views we create. Those bits of common behaviour are implemented in REST framework's mixin classes. +The create/retrieve/update/delete operations that we've been using so far are going to be pretty similar for any model-backed API views we create. Those bits of common behaviour are implemented in REST framework's mixin classes. Let's take a look at how we can compose our views by using the mixin classes. From 2761d6a4724d3dc60f817ab0718446564ca62f80 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 7 Aug 2013 20:27:41 +0100 Subject: [PATCH 07/23] Added @kolvia. For multiple documentation fixes in #1026. Thank you! :) --- docs/topics/credits.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/topics/credits.md b/docs/topics/credits.md index d1fa3681d..855ee479e 100644 --- a/docs/topics/credits.md +++ b/docs/topics/credits.md @@ -152,7 +152,8 @@ The following people have helped make REST framework great. * Kevin Brown - [kevin-brown] * Rodrigo Martell - [coderigo] * James Rutherford - [jimr] -* ricky rosario - [rlr] +* Ricky Rosario - [rlr] +* Veronica Lynn - [kolvia] Many thanks to everyone who's contributed to the project. @@ -342,3 +343,4 @@ You can also contact [@_tomchristie][twitter] directly on twitter. [kevin-brown]: https://github.com/kevin-brown [jimr]: https://github.com/jimr [rlr]: https://github.com/rlr +[kolvia]: https://github.com/kolvia From edd696292ca50cb9c10b50b0124a79135d007ea4 Mon Sep 17 00:00:00 2001 From: Dan Stephenson Date: Sat, 10 Aug 2013 01:12:36 +0100 Subject: [PATCH 08/23] Spelling correction on read_only_fields err msg --- rest_framework/serializers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 682a99a47..25825df4a 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -683,7 +683,7 @@ class ModelSerializer(Serializer): # in the `read_only_fields` option for field_name in self.opts.read_only_fields: assert field_name not in self.base_fields.keys(), \ - "field '%s' on serializer '%s' specfied in " \ + "field '%s' on serializer '%s' specified in " \ "`read_only_fields`, but also added " \ "as an explict field. Remove it from `read_only_fields`." % \ (field_name, self.__class__.__name__) From bbdcbe945248c5448540a1ab746b8a4b8bc8f95b Mon Sep 17 00:00:00 2001 From: Dan Stephenson Date: Sat, 10 Aug 2013 01:22:47 +0100 Subject: [PATCH 09/23] Spelling correction on read_only_fields err msg just spotted extras --- rest_framework/serializers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 682a99a47..9e85cb463 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -685,10 +685,10 @@ class ModelSerializer(Serializer): assert field_name not in self.base_fields.keys(), \ "field '%s' on serializer '%s' specfied in " \ "`read_only_fields`, but also added " \ - "as an explict field. Remove it from `read_only_fields`." % \ + "as an explicit field. Remove it from `read_only_fields`." % \ (field_name, self.__class__.__name__) assert field_name in ret, \ - "Noexistant field '%s' specified in `read_only_fields` " \ + "Non-existant field '%s' specified in `read_only_fields` " \ "on serializer '%s'." % \ (field_name, self.__class__.__name__) ret[field_name].read_only = True From 54b7b6760c40d9820268207a44996e2118430744 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 12 Aug 2013 09:27:34 +0100 Subject: [PATCH 10/23] Added @etos. For fixes in #1029, #1030 - Thanks! --- docs/topics/credits.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/topics/credits.md b/docs/topics/credits.md index 855ee479e..c563971c1 100644 --- a/docs/topics/credits.md +++ b/docs/topics/credits.md @@ -154,6 +154,7 @@ The following people have helped make REST framework great. * James Rutherford - [jimr] * Ricky Rosario - [rlr] * Veronica Lynn - [kolvia] +* Dan Stephenson - [etos] Many thanks to everyone who's contributed to the project. @@ -344,3 +345,4 @@ You can also contact [@_tomchristie][twitter] directly on twitter. [jimr]: https://github.com/jimr [rlr]: https://github.com/rlr [kolvia]: https://github.com/kolvia +[etos]: https://github.com/etos From cd5f1bb229f82cb1bf00c322fd5b688cf0638e97 Mon Sep 17 00:00:00 2001 From: Yuri Prezument Date: Mon, 12 Aug 2013 15:41:48 +0300 Subject: [PATCH 11/23] Fix PATCH button title in template --- rest_framework/templates/rest_framework/base.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_framework/templates/rest_framework/base.html b/rest_framework/templates/rest_framework/base.html index 9d939e738..51f9c2916 100644 --- a/rest_framework/templates/rest_framework/base.html +++ b/rest_framework/templates/rest_framework/base.html @@ -196,7 +196,7 @@ {% endif %} {% if raw_data_patch_form %} - + {% endif %} From 770d496307f1f9d3c8a95a167a506e59302f0de4 Mon Sep 17 00:00:00 2001 From: martync Date: Tue, 13 Aug 2013 09:19:40 +0200 Subject: [PATCH 12/23] Small typo --- docs/tutorial/6-viewsets-and-routers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorial/6-viewsets-and-routers.md b/docs/tutorial/6-viewsets-and-routers.md index f16add39d..8a1a1ae0c 100644 --- a/docs/tutorial/6-viewsets-and-routers.md +++ b/docs/tutorial/6-viewsets-and-routers.md @@ -10,7 +10,7 @@ A `ViewSet` class is only bound to a set of method handlers at the last moment, Let's take our current set of views, and refactor them into view sets. -First of all let's refactor our `UserList` and `UserDetail` views into a single `UserViewSet`. We can remove the two views, and replace then with a single class: +First of all let's refactor our `UserList` and `UserDetail` views into a single `UserViewSet`. We can remove the two views, and replace them with a single class: from rest_framework import viewsets From 999056cde1c6355d5ca036f109b35b41cb9d47cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20Gro=C3=9F?= Date: Tue, 13 Aug 2013 10:43:07 +0200 Subject: [PATCH 13/23] Add @martync for #1033 thanks! --- docs/topics/credits.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/topics/credits.md b/docs/topics/credits.md index c563971c1..b91f051b8 100644 --- a/docs/topics/credits.md +++ b/docs/topics/credits.md @@ -155,6 +155,7 @@ The following people have helped make REST framework great. * Ricky Rosario - [rlr] * Veronica Lynn - [kolvia] * Dan Stephenson - [etos] +* Martin Clement - [martync] Many thanks to everyone who's contributed to the project. @@ -346,3 +347,4 @@ You can also contact [@_tomchristie][twitter] directly on twitter. [rlr]: https://github.com/rlr [kolvia]: https://github.com/kolvia [etos]: https://github.com/etos +[martync]: https://github.com/martync From 1d8a80f5cc41f157403771439f15c9b7d615a43b Mon Sep 17 00:00:00 2001 From: Jeremy Satterfield Date: Tue, 13 Aug 2013 15:31:58 -0500 Subject: [PATCH 14/23] don't set X-Throttle-Wait-Second header if throttle wait is None --- rest_framework/tests/test_throttling.py | 33 ++++++++++++++++++++++++- rest_framework/views.py | 2 +- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/rest_framework/tests/test_throttling.py b/rest_framework/tests/test_throttling.py index 19bc691ae..41bff6926 100644 --- a/rest_framework/tests/test_throttling.py +++ b/rest_framework/tests/test_throttling.py @@ -7,7 +7,7 @@ from django.contrib.auth.models import User from django.core.cache import cache from rest_framework.test import APIRequestFactory from rest_framework.views import APIView -from rest_framework.throttling import UserRateThrottle, ScopedRateThrottle +from rest_framework.throttling import BaseThrottle, UserRateThrottle, ScopedRateThrottle from rest_framework.response import Response @@ -21,6 +21,14 @@ class User3MinRateThrottle(UserRateThrottle): scope = 'minutes' +class NonTimeThrottle(BaseThrottle): + def allow_request(self, request, view): + if not hasattr(self.__class__, 'called'): + self.__class__.called = True + return True + return False + + class MockView(APIView): throttle_classes = (User3SecRateThrottle,) @@ -35,6 +43,13 @@ class MockView_MinuteThrottling(APIView): return Response('foo') +class MockView_NonTimeThrottling(APIView): + throttle_classes = (NonTimeThrottle,) + + def get(self, request): + return Response('foo') + + class ThrottlingTests(TestCase): def setUp(self): """ @@ -140,6 +155,22 @@ class ThrottlingTests(TestCase): (80, None) )) + def test_non_time_throttle(self): + """ + Ensure for second based throttles. + """ + request = self.factory.get('/') + + self.assertFalse(hasattr(MockView_NonTimeThrottling.throttle_classes[0], 'called')) + + response = MockView_NonTimeThrottling.as_view()(request) + self.assertFalse('X-Throttle-Wait-Seconds' in response) + + self.assertTrue(MockView_NonTimeThrottling.throttle_classes[0].called) + + response = MockView_NonTimeThrottling.as_view()(request) + self.assertFalse('X-Throttle-Wait-Seconds' in response) + class ScopedRateThrottleTests(TestCase): """ diff --git a/rest_framework/views.py b/rest_framework/views.py index 37bba7f02..d51233a93 100644 --- a/rest_framework/views.py +++ b/rest_framework/views.py @@ -269,7 +269,7 @@ class APIView(View): Handle any exception that occurs, by returning an appropriate response, or re-raising the error. """ - if isinstance(exc, exceptions.Throttled): + if isinstance(exc, exceptions.Throttled) and exc.wait is not None: # Throttle wait header self.headers['X-Throttle-Wait-Seconds'] = '%d' % exc.wait From 2f03870ae12479cbfdce68db1a30bad6fa15b311 Mon Sep 17 00:00:00 2001 From: JT Date: Tue, 13 Aug 2013 18:48:49 -0500 Subject: [PATCH 15/23] Fix for "No module named compat" --- rest_framework/fields.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_framework/fields.py b/rest_framework/fields.py index f99318877..add9d224d 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -924,7 +924,7 @@ class ImageField(FileField): if f is None: return None - from compat import Image + from rest_framework.compat import Image assert Image is not None, 'PIL must be installed for ImageField support' # We need to get a file object for PIL. We might have a path or we might From 7bc63fbb11525c37fa73e1ffa9a6409a48aab4ac Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 14 Aug 2013 13:17:30 +0100 Subject: [PATCH 16/23] Added @jsatt. For fix & tests in #1037. --- docs/topics/credits.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/topics/credits.md b/docs/topics/credits.md index b91f051b8..1b34d5e0c 100644 --- a/docs/topics/credits.md +++ b/docs/topics/credits.md @@ -156,6 +156,7 @@ The following people have helped make REST framework great. * Veronica Lynn - [kolvia] * Dan Stephenson - [etos] * Martin Clement - [martync] +* Jeremy Satterfield - [jsatt] Many thanks to everyone who's contributed to the project. @@ -348,3 +349,4 @@ You can also contact [@_tomchristie][twitter] directly on twitter. [kolvia]: https://github.com/kolvia [etos]: https://github.com/etos [martync]: https://github.com/martync +[jsatt]: https://github.com/jsatt From 486f4c8047b18cc753e1969079b58ca3da6ab43f Mon Sep 17 00:00:00 2001 From: Chad Barrington Date: Wed, 14 Aug 2013 15:18:44 -0500 Subject: [PATCH 17/23] Update filters.py Here's a little cleanup for ya, brah! --- rest_framework/filters.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_framework/filters.py b/rest_framework/filters.py index c058bc715..fbfdd099e 100644 --- a/rest_framework/filters.py +++ b/rest_framework/filters.py @@ -134,7 +134,7 @@ class OrderingFilter(BaseFilterBackend): ordering = self.remove_invalid_fields(queryset, ordering) if not ordering: - # Use 'ordering' attribtue by default + # Use 'ordering' attribute by default ordering = self.get_default_ordering(view) if ordering: From 99083baf25d3145d034336b2569b79488cf1662b Mon Sep 17 00:00:00 2001 From: Chad Barrington Date: Wed, 14 Aug 2013 16:01:25 -0500 Subject: [PATCH 18/23] Update filters.py Fixed cut n pasted get_ordering docstring for ya bro. --- rest_framework/filters.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/rest_framework/filters.py b/rest_framework/filters.py index fbfdd099e..4079e1bd5 100644 --- a/rest_framework/filters.py +++ b/rest_framework/filters.py @@ -109,8 +109,7 @@ class OrderingFilter(BaseFilterBackend): def get_ordering(self, request): """ - Search terms are set by a ?search=... query parameter, - and may be comma and/or whitespace delimited. + Ordering is set by a comma delimited ?ordering=... query parameter. """ params = request.QUERY_PARAMS.get(self.ordering_param) if params: From f34b9ff0498ca054bfe65b4da99b01d48ff052b8 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 15 Aug 2013 21:36:45 +0100 Subject: [PATCH 19/23] AnonRateThrottle should always allow authenticated users. Closes #994 --- rest_framework/throttling.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rest_framework/throttling.py b/rest_framework/throttling.py index f6bb1cc84..65b455930 100644 --- a/rest_framework/throttling.py +++ b/rest_framework/throttling.py @@ -96,6 +96,9 @@ class SimpleRateThrottle(BaseThrottle): return True self.key = self.get_cache_key(request, view) + if self.key is None: + return True + self.history = cache.get(self.key, []) self.now = self.timer() From d5b56310b0cc99df1cd1e61fc35f251c46036d62 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 16 Aug 2013 13:23:27 +0100 Subject: [PATCH 20/23] Update release notes --- docs/topics/release-notes.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/topics/release-notes.md b/docs/topics/release-notes.md index d379ab74f..876f46d8c 100644 --- a/docs/topics/release-notes.md +++ b/docs/topics/release-notes.md @@ -40,6 +40,17 @@ You can determine your currently installed version using `pip freeze`: ## 2.3.x series +### master + +* Added `APITestClient`, `APIRequestFactory` and `APITestCase` etc... +* Refactor `SessionAuthentication` to allow esier override for CSRF exemption. +* Remove 'Hold down "Control" message from help_text". +* Added admin configuration for 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 From 13ca305b06a6d9bf982559640fa488f7ad31e2f8 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 16 Aug 2013 13:27:21 +0100 Subject: [PATCH 21/23] Tweak docs. --- docs/api-guide/permissions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api-guide/permissions.md b/docs/api-guide/permissions.md index 096ef3691..c6372f981 100644 --- a/docs/api-guide/permissions.md +++ b/docs/api-guide/permissions.md @@ -196,7 +196,7 @@ The following third party packages are also available. ## DRF Any Permissions -The [DRF Any Permissions][drf-any-permissions] packages provides a different permission behavior in contrast to the REST framework. Only one of the given permissions has to be true in order to get access to the view. +The [DRF Any Permissions][drf-any-permissions] packages provides a different permission behavior in contrast to REST framework. Instead of all specified permissions being required, only one of the given permissions has to be true in order to get access to the view. [cite]: https://developer.apple.com/library/mac/#documentation/security/Conceptual/AuthenticationAndAuthorizationGuide/Authorization/Authorization.html [authentication]: authentication.md From f6f69dc71d4db7492b5feecc69627dff0031e2b9 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 16 Aug 2013 14:03:20 +0100 Subject: [PATCH 22/23] Version 2.3.7 --- docs/topics/release-notes.md | 8 +++++--- rest_framework/__init__.py | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/topics/release-notes.md b/docs/topics/release-notes.md index 876f46d8c..624d9acd4 100644 --- a/docs/topics/release-notes.md +++ b/docs/topics/release-notes.md @@ -40,12 +40,14 @@ You can determine your currently installed version using `pip freeze`: ## 2.3.x series -### master +### 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". -* Added admin configuration for tokens. +* 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. diff --git a/rest_framework/__init__.py b/rest_framework/__init__.py index 776618ac3..087808e0b 100644 --- a/rest_framework/__init__.py +++ b/rest_framework/__init__.py @@ -1,4 +1,4 @@ -__version__ = '2.3.6' +__version__ = '2.3.7' VERSION = __version__ # synonym From c1ccd8b5b5aef1bd209862f9431c9c03e25ae755 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 16 Aug 2013 14:12:24 +0100 Subject: [PATCH 23/23] Update docs to include testing. --- docs/index.md | 2 ++ docs/template.html | 1 + mkdocs.py | 1 + 3 files changed, 4 insertions(+) diff --git a/docs/index.md b/docs/index.md index 99cd6b882..a0ae2984d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -164,6 +164,7 @@ The API guide is your complete reference manual to all the functionality provide * [Returning URLs][reverse] * [Exceptions][exceptions] * [Status codes][status] +* [Testing][testing] * [Settings][settings] ## Topics @@ -288,6 +289,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [reverse]: api-guide/reverse.md [exceptions]: api-guide/exceptions.md [status]: api-guide/status-codes.md +[testing]: api-guide/testing.md [settings]: api-guide/settings.md [documenting-your-api]: topics/documenting-your-api.md diff --git a/docs/template.html b/docs/template.html index 27bc10622..a20c81110 100644 --- a/docs/template.html +++ b/docs/template.html @@ -89,6 +89,7 @@
  • Returning URLs
  • Exceptions
  • Status codes
  • +
  • Testing
  • Settings
  • diff --git a/mkdocs.py b/mkdocs.py index 1e3f1db3f..13228a0ce 100755 --- a/mkdocs.py +++ b/mkdocs.py @@ -69,6 +69,7 @@ path_list = [ 'api-guide/reverse.md', 'api-guide/exceptions.md', 'api-guide/status-codes.md', + 'api-guide/testing.md', 'api-guide/settings.md', 'topics/documenting-your-api.md', 'topics/ajax-csrf-cors.md',