diff options
Diffstat (limited to 'docs/api-guide')
| -rwxr-xr-x | docs/api-guide/authentication.md | 10 | ||||
| -rw-r--r-- | docs/api-guide/exceptions.md | 8 | ||||
| -rw-r--r-- | docs/api-guide/fields.md | 8 | ||||
| -rw-r--r-- | docs/api-guide/filtering.md | 9 | ||||
| -rwxr-xr-x | docs/api-guide/generic-views.md | 4 | ||||
| -rw-r--r-- | docs/api-guide/parsers.md | 6 | ||||
| -rw-r--r-- | docs/api-guide/permissions.md | 5 | ||||
| -rw-r--r-- | docs/api-guide/relations.md | 18 | ||||
| -rw-r--r-- | docs/api-guide/renderers.md | 27 | ||||
| -rw-r--r-- | docs/api-guide/routers.md | 34 | ||||
| -rw-r--r-- | docs/api-guide/serializers.md | 2 | ||||
| -rw-r--r-- | docs/api-guide/status-codes.md | 21 | ||||
| -rw-r--r-- | docs/api-guide/views.md | 4 | ||||
| -rw-r--r-- | docs/api-guide/viewsets.md | 2 |
14 files changed, 141 insertions, 17 deletions
diff --git a/docs/api-guide/authentication.md b/docs/api-guide/authentication.md index 7caeac1e..53efc49a 100755 --- a/docs/api-guide/authentication.md +++ b/docs/api-guide/authentication.md @@ -162,10 +162,12 @@ The `curl` command line tool may be useful for testing token authenticated APIs. If you want every user to have an automatically generated Token, you can simply catch the User's `post_save` signal. + from django.contrib.auth import get_user_model + from django.db.models.signals import post_save from django.dispatch import receiver from rest_framework.authtoken.models import Token - @receiver(post_save, sender=User) + @receiver(post_save, sender=get_user_model()) def create_auth_token(sender, instance=None, created=False, **kwargs): if created: Token.objects.create(user=instance) @@ -265,6 +267,12 @@ This authentication class depends on the optional [django-oauth2-provider][djang 'provider.oauth2', ) +Then add `OAuth2Authentication` to your global `DEFAULT_AUTHENTICATION` setting: + + 'DEFAULT_AUTHENTICATION_CLASSES': ( + 'rest_framework.authentication.OAuth2Authentication', + ), + You must also include the following in your root `urls.py` module: url(r'^oauth2/', include('provider.oauth2.urls', namespace='oauth2')), diff --git a/docs/api-guide/exceptions.md b/docs/api-guide/exceptions.md index c46d415e..221df679 100644 --- a/docs/api-guide/exceptions.md +++ b/docs/api-guide/exceptions.md @@ -88,6 +88,14 @@ The **base class** for all exceptions raised inside REST framework. To provide a custom exception, subclass `APIException` and set the `.status_code` and `.detail` properties on the class. +For example, if your API relies on a third party service that may sometimes be unreachable, you might want to implement an exception for the "503 Service Unavailable" HTTP response code. You could do this like so: + + from rest_framework.exceptions import APIException + + class ServiceUnavailable(APIException): + status_code = 503 + detail = 'Service temporarily unavailable, try again later.' + ## ParseError **Signature:** `ParseError(detail=None)` diff --git a/docs/api-guide/fields.md b/docs/api-guide/fields.md index 962c49e2..e05c0306 100644 --- a/docs/api-guide/fields.md +++ b/docs/api-guide/fields.md @@ -41,7 +41,7 @@ Defaults to `True`. ### `default` -If set, this gives the default value that will be used for the field if none is supplied. If not set the default behavior is to not populate the attribute at all. +If set, this gives the default value that will be used for the field if no input value is supplied. If not set the default behavior is to not populate the attribute at all. May be set to a function or other callable, in which case the value will be evaluated each time it is used. @@ -286,7 +286,7 @@ An image representation. Corresponds to `django.forms.fields.ImageField`. -Requires the `PIL` package. +Requires either the `Pillow` package or `PIL` package. The `Pillow` package is recommended, as `PIL` is no longer actively maintained. Signature and validation is the same as with `FileField`. @@ -299,9 +299,9 @@ Django's regular [FILE_UPLOAD_HANDLERS] are used for handling uploaded files. # Custom fields -If you want to create a custom field, you'll probably want to override either one or both of the `.to_native()` and `.from_native()` methods. These two methods are used to convert between the initial datatype, and a primative, serializable datatype. Primative datatypes may be any of a number, string, date/time/datetime or None. They may also be any list or dictionary like object that only contains other primative objects. +If you want to create a custom field, you'll probably want to override either one or both of the `.to_native()` and `.from_native()` methods. These two methods are used to convert between the initial datatype, and a primitive, serializable datatype. Primitive datatypes may be any of a number, string, date/time/datetime or None. They may also be any list or dictionary like object that only contains other primitive objects. -The `.to_native()` method is called to convert the initial datatype into a primative, serializable datatype. The `from_native()` method is called to restore a primative datatype into it's initial representation. +The `.to_native()` method is called to convert the initial datatype into a primitive, serializable datatype. The `from_native()` method is called to restore a primitive datatype into it's initial representation. ## Examples diff --git a/docs/api-guide/filtering.md b/docs/api-guide/filtering.md index a0132ffc..0e02a2a7 100644 --- a/docs/api-guide/filtering.md +++ b/docs/api-guide/filtering.md @@ -360,6 +360,14 @@ For example, you might need to restrict users to only being able to see objects We could achieve the same behavior by overriding `get_queryset()` on the views, but using a filter backend allows you to more easily add this restriction to multiple views, or to apply it across the entire API. +# Third party packages + +The following third party packages provide additional filter implementations. + +## Django REST framework chain + +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. + [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 @@ -368,3 +376,4 @@ We could achieve the same behavior by overriding `get_queryset()` on the views, [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 diff --git a/docs/api-guide/generic-views.md b/docs/api-guide/generic-views.md index b9242724..83c3e45f 100755 --- a/docs/api-guide/generic-views.md +++ b/docs/api-guide/generic-views.md @@ -163,12 +163,14 @@ For example: return 20 return 100 -**Save hooks**: +**Save / deletion hooks**: The following methods are provided as placeholder interfaces. They contain empty implementations and are not called directly by `GenericAPIView`, but they are overridden and used by some of the mixin classes. * `pre_save(self, obj)` - A hook that is called before saving an object. * `post_save(self, obj, created=False)` - A hook that is called after saving an object. +* `pre_delete(self, obj)` - A hook that is called before deleting an object. +* `post_delete(self, obj)` - A hook that is called after deleting an object. The `pre_save` method in particular is a useful hook for setting attributes that are implicit in the request, but are not part of the request data. For instance, you might set an attribute on the object based on the request user, or based on a URL keyword argument. diff --git a/docs/api-guide/parsers.md b/docs/api-guide/parsers.md index 1030fcb6..72a4af64 100644 --- a/docs/api-guide/parsers.md +++ b/docs/api-guide/parsers.md @@ -186,9 +186,15 @@ The following third party packages are also available. [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. +## CamelCase JSON + +[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]. + [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 [messagepack]: https://github.com/juanriaza/django-rest-framework-msgpack [juanriaza]: https://github.com/juanriaza +[vbabiy]: https://github.com/vbabiy [djangorestframework-msgpack]: https://github.com/juanriaza/django-rest-framework-msgpack +[djangorestframework-camel-case]: https://github.com/vbabiy/djangorestframework-camel-case
\ No newline at end of file diff --git a/docs/api-guide/permissions.md b/docs/api-guide/permissions.md index 871de84e..6a0f48f4 100644 --- a/docs/api-guide/permissions.md +++ b/docs/api-guide/permissions.md @@ -230,6 +230,10 @@ The [DRF Any Permissions][drf-any-permissions] packages provides a different per The [Composed Permissions][composed-permissions] package provides a simple way to define complex and multi-depth (with logic operators) permission objects, using small and reusable components. +## REST Condition + +The [REST Condition][rest-condition] package is another extension for building complex permissions in a simple and convenient way. The extension allows you to combine permissions with logical operators. + [cite]: https://developer.apple.com/library/mac/#documentation/security/Conceptual/AuthenticationAndAuthorizationGuide/Authorization/Authorization.html [authentication]: authentication.md [throttling]: throttling.md @@ -243,3 +247,4 @@ The [Composed Permissions][composed-permissions] package provides a simple way t [filtering]: filtering.md [drf-any-permissions]: https://github.com/kevin-brown/drf-any-permissions [composed-permissions]: https://github.com/niwibe/djangorestframework-composed-permissions +[rest-condition]: https://github.com/caxap/rest_condition diff --git a/docs/api-guide/relations.md b/docs/api-guide/relations.md index b9d96b5e..cc4f5585 100644 --- a/docs/api-guide/relations.md +++ b/docs/api-guide/relations.md @@ -44,7 +44,7 @@ In order to explain the various types of relational fields, we'll use a couple o For example, the following serializer. class AlbumSerializer(serializers.ModelSerializer): - tracks = RelatedField(many=True) + tracks = serializers.RelatedField(many=True) class Meta: model = Album @@ -134,7 +134,7 @@ By default this field is read-write, although you can change this behavior using **Arguments**: -* `view_name` - The view name that should be used as the target of the relationship. **required**. +* `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 wil be a string with the format `<modelname>-detail`. **required**. * `many` - If applied to a to-many relationship, you should set this argument to `True`. * `required` - If set to `False`, the field will accept values of `None` or the empty-string for nullable relationships. * `queryset` - By default `ModelSerializer` classes will use the default queryset for the relationship. `Serializer` classes must either set a queryset explicitly, or set `read_only=True`. @@ -202,7 +202,7 @@ This field is always read-only. **Arguments**: -* `view_name` - The view name that should be used as the target of the relationship. **required**. +* `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 wil be a string with the format `<model_name>-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'`. * `format` - If using format suffixes, hyperlinked fields will use the same format suffix for the target unless overridden by using the `format` argument. @@ -442,7 +442,19 @@ In the 2.4 release, these parts of the API will be removed entirely. For more details see the [2.2 release announcement][2.2-announcement]. +--- + +# Third Party Packages + +The following third party packages are also available. + +## DRF Nested Routers + +The [drf-nested-routers package][drf-nested-routers] provides routers and relationship fields for working with nested resources. + [cite]: http://lwn.net/Articles/193245/ [reverse-relationships]: https://docs.djangoproject.com/en/dev/topics/db/queries/#following-relationships-backward +[routers]: http://www.django-rest-framework.org/api-guide/routers#defaultrouter [generic-relations]: https://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/#id1 [2.2-announcement]: ../topics/2.2-announcement.md +[drf-nested-routers]: https://github.com/alanjds/drf-nested-routers diff --git a/docs/api-guide/renderers.md b/docs/api-guide/renderers.md index 657377d9..7798827b 100644 --- a/docs/api-guide/renderers.md +++ b/docs/api-guide/renderers.md @@ -118,7 +118,13 @@ Renders the request data into `JSONP`. The `JSONP` media type provides a mechan The javascript callback function must be set by the client including a `callback` URL query parameter. For example `http://example.com/api/users?callback=jsonpCallback`. If the callback function is not explicitly set by the client it will default to `'callback'`. -**Note**: If you require cross-domain AJAX requests, you may want to consider using the more modern approach of [CORS][cors] as an alternative to `JSONP`. See the [CORS documentation][cors-docs] for more details. +--- + +**Warning**: If you require cross-domain AJAX requests, you should almost certainly 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. + +--- **.media_type**: `application/javascript` @@ -167,14 +173,14 @@ The template name is determined by (in order of preference): An example of a view that uses `TemplateHTMLRenderer`: - class UserDetail(generics.RetrieveUserAPIView): + class UserDetail(generics.RetrieveAPIView): """ A view that returns a templated HTML representations of a given user. """ queryset = User.objects.all() renderer_classes = (TemplateHTMLRenderer,) - def get(self, request, *args, **kwargs) + def get(self, request, *args, **kwargs): self.object = self.get_object() return Response({'user': self.object}, template_name='user_detail.html') @@ -409,12 +415,22 @@ The following third party packages are also available. 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 + +[UltraJSON][ultrajson] is an optimized C JSON encoder which can give significantly faster JSON rendering. [Jacob Haslehurst][hzy] maintains the [drf-ujson-renderer][drf-ujson-renderer] package which implements JSON rendering using the UJSON package. + +## CamelCase JSON + +[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]. + + [cite]: https://docs.djangoproject.com/en/dev/ref/template-response/#the-rendering-process [conneg]: content-negotiation.md [browser-accept-headers]: http://www.gethifi.com/blog/browser-rest-http-accept-headers [rfc4627]: http://www.ietf.org/rfc/rfc4627.txt [cors]: http://www.w3.org/TR/cors/ [cors-docs]: ../topics/ajax-csrf-cors.md +[jsonp-security]: http://stackoverflow.com/questions/613962/is-jsonp-safe-to-use [testing]: testing.md [HATEOAS]: http://timelessrepo.com/haters-gonna-hateoas [quote]: http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven @@ -424,5 +440,10 @@ Comma-separated values are a plain-text tabular data format, that can be easily [messagepack]: http://msgpack.org/ [juanriaza]: https://github.com/juanriaza [mjumbewu]: https://github.com/mjumbewu +[vbabiy]: https://github.com/vbabiy [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 +[hzy]: https://github.com/hzy +[drf-ujson-renderer]: https://github.com/gizmag/drf-ujson-renderer +[djangorestframework-camel-case]: https://github.com/vbabiy/djangorestframework-camel-case
\ No newline at end of file diff --git a/docs/api-guide/routers.md b/docs/api-guide/routers.md index fb48197e..7efc140a 100644 --- a/docs/api-guide/routers.md +++ b/docs/api-guide/routers.md @@ -12,7 +12,7 @@ REST framework adds support for automatic URL routing to Django, and provides yo ## Usage -Here's an example of a simple URL conf, that uses `DefaultRouter`. +Here's an example of a simple URL conf, that uses `SimpleRouter`. from rest_framework import routers @@ -37,6 +37,18 @@ The example above would generate the following URL patterns: * URL pattern: `^accounts/$` Name: `'account-list'` * URL pattern: `^accounts/{pk}/$` Name: `'account-detail'` +--- + +**Note**: The `base_name` argument is used to specify the initial part of the view name pattern. In the example above, that's the `user` or `account` part. + +Typically you won't *need* to specify the `base-name` argument, but if you have a viewset where you've defined a custom `get_queryset` method, then the viewset may not have any `.model` or `.queryset` attribute set. If you try to register that viewset you'll see an error like this: + + 'base_name' argument not specified, and could not automatically determine the name from the viewset, as it does not have a '.model' or '.queryset' attribute. + +This means you'll need to explicitly set the `base_name` argument when registering the viewset, as it could not be automatically determined from the model name. + +--- + ### Extra link and actions Any methods on the viewset decorated with `@link` or `@action` will also be routed. @@ -150,4 +162,24 @@ If you want to provide totally custom behavior, you can override `BaseRouter` an 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. +# Third Party Packages + +The following third party packages are also available. + +## DRF Nested Routers + +The [drf-nested-routers package][drf-nested-routers] provides routers and relationship fields for working with nested resources. + +## wq.db + +The [wq.db package][wq.db] provides an advanced [Router][wq.db-router] class (and singleton instance) that extends `DefaultRouter` with a `register_model()` API. Much like Django's `admin.site.register`, the only required argument to `app.router.register_model` is a model class. Reasonable defaults for a url prefix and viewset will be inferred from the model and global configuration. + + from wq.db.rest import app + from myapp.models import MyModel + + app.router.register_model(MyModel) + [cite]: http://guides.rubyonrails.org/routing.html +[drf-nested-routers]: https://github.com/alanjds/drf-nested-routers +[wq.db]: http://wq.io/wq.db +[wq.db-router]: http://wq.io/docs/app.py diff --git a/docs/api-guide/serializers.md b/docs/api-guide/serializers.md index 4c3fb9d3..6fc25f57 100644 --- a/docs/api-guide/serializers.md +++ b/docs/api-guide/serializers.md @@ -425,7 +425,7 @@ You can change the field that is used for object lookups by setting the `lookup_ fields = ('url', 'account_name', 'users', 'created') lookup_field = 'slug' -Not that the `lookup_field` will be used as the default on *all* hyperlinked fields, including both the URL identity, and any hyperlinked relationships. +Note 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 specific requirements such as specifying a different lookup for each field, you'll want to set the fields on the serializer explicitly. For example: diff --git a/docs/api-guide/status-codes.md b/docs/api-guide/status-codes.md index 409f659b..64c46434 100644 --- a/docs/api-guide/status-codes.md +++ b/docs/api-guide/status-codes.md @@ -17,6 +17,18 @@ Using bare status codes in your responses isn't recommended. REST framework inc The full set of HTTP status codes included in the `status` module is listed below. +The module also includes a set of helper functions for testing if a status code is in a given range. + + from rest_framework import status + from rest_framework.test import APITestCase + + class ExampleTestCase(APITestCase): + def test_url_root(self): + url = reverse('index') + response = self.client.get(url) + self.assertTrue(status.is_success(response.status_code)) + + For more information on proper usage of HTTP status codes see [RFC 2616][rfc2616] and [RFC 6585][rfc6585]. @@ -90,6 +102,15 @@ Response status codes beginning with the digit "5" indicate cases in which the s HTTP_505_HTTP_VERSION_NOT_SUPPORTED HTTP_511_NETWORK_AUTHENTICATION_REQUIRED +## Helper functions + +The following helper functions are available for identifying the category of the response code. + + is_informational() # 1xx + is_success() # 2xx + is_redirect() # 3xx + is_client_error() # 4xx + is_server_error() # 5xx [rfc2324]: http://www.ietf.org/rfc/rfc2324.txt [rfc2616]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html diff --git a/docs/api-guide/views.md b/docs/api-guide/views.md index 15581e09..194a7a6b 100644 --- a/docs/api-guide/views.md +++ b/docs/api-guide/views.md @@ -168,5 +168,5 @@ Each of these decorators takes a single argument which must be a list or tuple o [cite]: http://reinout.vanrees.org/weblog/2011/08/24/class-based-views-usage.html [cite2]: http://www.boredomandlaziness.org/2012/05/djangos-cbvs-are-not-mistake-but.html -[settings]: api-guide/settings.md -[throttling]: api-guide/throttling.md +[settings]: settings.md +[throttling]: throttling.md diff --git a/docs/api-guide/viewsets.md b/docs/api-guide/viewsets.md index 1062cb32..4fdd9364 100644 --- a/docs/api-guide/viewsets.md +++ b/docs/api-guide/viewsets.md @@ -170,7 +170,7 @@ The actions provided by the `ModelViewSet` class are `.list()`, `.retrieve()`, #### Example -Because `ModelViewSet` extends `GenericAPIView`, you'll normally need to provide at least the `queryset` and `serializer_class` attributes. For example: +Because `ModelViewSet` extends `GenericAPIView`, you'll normally need to provide at least the `queryset` and `serializer_class` attributes, or the `model` attribute shortcut. For example: class AccountViewSet(viewsets.ModelViewSet): """ |
