diff --git a/docs/api-guide/authentication.md b/docs/api-guide/authentication.md index 01774c10d..b04858e39 100755 --- a/docs/api-guide/authentication.md +++ b/docs/api-guide/authentication.md @@ -1,4 +1,4 @@ - +source: authentication.py # Authentication diff --git a/docs/api-guide/content-negotiation.md b/docs/api-guide/content-negotiation.md index 94dd59cac..bc3b09fb7 100644 --- a/docs/api-guide/content-negotiation.md +++ b/docs/api-guide/content-negotiation.md @@ -1,4 +1,4 @@ - +source: negotiation.py # Content negotiation @@ -29,7 +29,7 @@ The priorities for each of the given media types would be: If the requested view was only configured with renderers for `YAML` and `HTML`, then REST framework would select whichever renderer was listed first in the `renderer_classes` list or `DEFAULT_RENDERER_CLASSES` setting. -For more information on the `HTTP Accept` header, see [RFC 2616][accept-header] +For more information on the `HTTP Accept` header, see [RFC 2616][accept-header] --- @@ -62,7 +62,7 @@ request when selecting the appropriate parser or renderer. Select the first parser in the `.parser_classes` list. """ return parsers[0] - + def select_renderer(self, request, renderers, format_suffix): """ Select the first renderer in the `.renderer_classes` list. diff --git a/docs/api-guide/exceptions.md b/docs/api-guide/exceptions.md index e61dcfa90..8e0b1958e 100644 --- a/docs/api-guide/exceptions.md +++ b/docs/api-guide/exceptions.md @@ -1,4 +1,4 @@ - +source: exceptions.py # Exceptions diff --git a/docs/api-guide/fields.md b/docs/api-guide/fields.md index 292a51d89..354ec9662 100644 --- a/docs/api-guide/fields.md +++ b/docs/api-guide/fields.md @@ -1,4 +1,4 @@ - +source: fields.py # Serializer fields @@ -62,7 +62,7 @@ A dictionary of error codes to error messages. ### `widget` Used only if rendering the field to HTML. -This argument sets the widget that should be used to render the field. For more details, and a list of available widgets, see [the Django documentation on form widgets][django-widgets]. +This argument sets the widget that should be used to render the field. For more details, and a list of available widgets, see [the Django documentation on form widgets][django-widgets]. ### `label` diff --git a/docs/api-guide/filtering.md b/docs/api-guide/filtering.md index cfeb43349..83977048f 100644 --- a/docs/api-guide/filtering.md +++ b/docs/api-guide/filtering.md @@ -1,4 +1,4 @@ - +source: filters.py # Filtering @@ -26,7 +26,7 @@ For example: class PurchaseList(generics.ListAPIView): serializer_class = PurchaseSerializer - + def get_queryset(self): """ This view should return a list of all the purchases @@ -38,7 +38,7 @@ For example: ## Filtering against the URL -Another style of filtering might involve restricting the queryset based on some part of the URL. +Another style of filtering might involve restricting the queryset based on some part of the URL. For example if your URL config contained an entry like this: @@ -48,7 +48,7 @@ You could then write a view that returned a purchase queryset filtered by the us class PurchaseList(generics.ListAPIView): serializer_class = PurchaseSerializer - + def get_queryset(self): """ This view should return a list of all the purchases for @@ -57,7 +57,7 @@ You could then write a view that returned a purchase queryset filtered by the us username = self.kwargs['username'] return Purchase.objects.filter(purchaser__username=username) -## Filtering against query parameters +## Filtering against query parameters A final example of filtering the initial queryset would be to determine the initial queryset based on query parameters in the url. @@ -65,7 +65,7 @@ We can override `.get_queryset()` to deal with URLs such as `http://example.com/ class PurchaseList(generics.ListAPIView): serializer_class = PurchaseSerializer - + def get_queryset(self): """ Optionally restricts the returned purchases to a given user, @@ -113,7 +113,7 @@ For instance, given the previous example, and a product with an id of `4675`, th http://example.com/api/products/4675/?category=clothing&max_price=10.00 ## Overriding the initial queryset - + Note that you can use both an overridden `.get_queryset()` and generic filtering together, and everything will work as expected. For example, if `Product` had a many-to-many relationship with `User`, named `purchase`, you might want to write a view like this: class PurchasedProductsList(generics.ListAPIView): @@ -124,7 +124,7 @@ Note that you can use both an overridden `.get_queryset()` and generic filtering model = Product serializer_class = ProductSerializer filter_class = ProductFilter - + def get_queryset(self): user = self.request.user return user.purchase_set.all() @@ -135,7 +135,7 @@ Note that you can use both an overridden `.get_queryset()` and generic filtering ## DjangoFilterBackend -The `DjangoFilterBackend` class supports highly customizable field filtering, using the [django-filter package][django-filter]. +The `DjangoFilterBackend` class supports highly customizable field filtering, using the [django-filter package][django-filter]. To use REST framework's `DjangoFilterBackend`, first install `django-filter`. @@ -216,7 +216,7 @@ This is nice, but it exposes the Django's double underscore convention as part o And now you can execute: http://example.com/api/products?manufacturer=foo - + For more details on using filter sets see the [django-filter documentation][django-filter-docs]. --- @@ -224,7 +224,7 @@ For more details on using filter sets see the [django-filter documentation][djan **Hints & Tips** * By default filtering is not enabled. If you want to use `DjangoFilterBackend` remember to make sure it is installed by using the `'DEFAULT_FILTER_BACKENDS'` setting. -* When using boolean fields, you should use the values `True` and `False` in the URL query parameters, rather than `0`, `1`, `true` or `false`. (The allowed boolean values are currently hardwired in Django's [NullBooleanSelect implementation][nullbooleanselect].) +* When using boolean fields, you should use the values `True` and `False` in the URL query parameters, rather than `0`, `1`, `true` or `false`. (The allowed boolean values are currently hardwired in Django's [NullBooleanSelect implementation][nullbooleanselect].) * `django-filter` supports filtering across relationships, using Django's double-underscore syntax. * For Django 1.3 support, make sure to install `django-filter` version 0.5.4, as later versions drop support for 1.3. @@ -316,7 +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 = ('username',) + ordering = ('username',) The `ordering` attribute may be either a string or a list/tuple of strings. diff --git a/docs/api-guide/format-suffixes.md b/docs/api-guide/format-suffixes.md index 76a3367b0..20c1e9952 100644 --- a/docs/api-guide/format-suffixes.md +++ b/docs/api-guide/format-suffixes.md @@ -1,4 +1,4 @@ - +source: urlpatterns.py # Format suffixes @@ -7,7 +7,7 @@ used all the time. > > — Roy Fielding, [REST discuss mailing list][cite] -A common pattern for Web APIs is to use filename extensions on URLs to provide an endpoint for a given media type. For example, 'http://example.com/api/users.json' to serve a JSON representation. +A common pattern for Web APIs is to use filename extensions on URLs to provide an endpoint for a given media type. For example, 'http://example.com/api/users.json' to serve a JSON representation. Adding format-suffix patterns to each individual entry in the URLconf for your API is error-prone and non-DRY, so REST framework provides a shortcut to adding these patterns to your URLConf. @@ -21,7 +21,7 @@ Arguments: * **urlpatterns**: Required. A URL pattern list. * **suffix_required**: Optional. A boolean indicating if suffixes in the URLs should be optional or mandatory. Defaults to `False`, meaning that suffixes are optional by default. -* **allowed**: Optional. A list or tuple of valid format suffixes. If not provided, a wildcard format suffix pattern will be used. +* **allowed**: Optional. A list or tuple of valid format suffixes. If not provided, a wildcard format suffix pattern will be used. Example: @@ -33,7 +33,7 @@ Example: url(r'^comments/$', views.comment_list), url(r'^comments/(?P[0-9]+)/$', views.comment_detail) ] - + urlpatterns = format_suffix_patterns(urlpatterns, allowed=['json', 'html']) When using `format_suffix_patterns`, you must make sure to add the `'format'` keyword argument to the corresponding views. For example: @@ -56,12 +56,12 @@ 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. --- - + ## Accept headers vs. format suffixes There seems to be a view among some of the Web community that filename extensions are not a RESTful pattern, and that `HTTP Accept` headers should always be used instead. -It is actually a misconception. For example, take the following quote from Roy Fielding discussing the relative merits of query parameter media-type indicators vs. file extension media-type indicators: +It is actually a misconception. For example, take the following quote from Roy Fielding discussing the relative merits of query parameter media-type indicators vs. file extension media-type indicators: “That's why I always prefer extensions. Neither choice has anything to do with REST.” — Roy Fielding, [REST discuss mailing list][cite2] diff --git a/docs/api-guide/generic-views.md b/docs/api-guide/generic-views.md index 49a5e58f0..648ece827 100755 --- a/docs/api-guide/generic-views.md +++ b/docs/api-guide/generic-views.md @@ -1,5 +1,5 @@ - - +source: mixins.py + generics.py # Generic views diff --git a/docs/api-guide/pagination.md b/docs/api-guide/pagination.md index e57aed1a9..9b7086c54 100644 --- a/docs/api-guide/pagination.md +++ b/docs/api-guide/pagination.md @@ -1,4 +1,4 @@ - +source: pagination.py # Pagination @@ -6,7 +6,7 @@ > > — [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 a `PaginationSerializer` class that makes it easy to return paginated data in a way that can then be rendered to arbitrary media types. ## Paginating basic data @@ -33,7 +33,7 @@ The `context` argument of the `PaginationSerializer` class may optionally includ 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']} + # {'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. diff --git a/docs/api-guide/parsers.md b/docs/api-guide/parsers.md index 72a4af643..42d77b223 100644 --- a/docs/api-guide/parsers.md +++ b/docs/api-guide/parsers.md @@ -1,4 +1,4 @@ - +source: parsers.py # Parsers @@ -161,7 +161,7 @@ By default this will include the following keys: `view`, `request`, `args`, `kwa ## Example -The following is an example plaintext parser that will populate the `request.DATA` property with a string representing the body of the request. +The following is an example plaintext parser that will populate the `request.DATA` property with a string representing the body of the request. class PlainTextParser(BaseParser): """ @@ -197,4 +197,4 @@ The following third party packages are also available. [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 +[djangorestframework-camel-case]: https://github.com/vbabiy/djangorestframework-camel-case diff --git a/docs/api-guide/permissions.md b/docs/api-guide/permissions.md index 446e362e1..f068f0f72 100644 --- a/docs/api-guide/permissions.md +++ b/docs/api-guide/permissions.md @@ -1,4 +1,4 @@ - +source: permissions.py # Permissions @@ -12,7 +12,7 @@ Permission checks are always run at the very start of the view, before any other ## How permissions are determined -Permissions in REST framework are always defined as a list of permission classes. +Permissions in REST framework are always defined as a list of permission classes. Before running the main body of the view each permission in the list is checked. If any permission check fails an `exceptions.PermissionDenied` exception will be raised, and the main body of the view will not run. @@ -220,9 +220,9 @@ As well as global permissions, that are run against all incoming requests, you c def has_object_permission(self, request, view, obj): # Read permissions are allowed to any request, # so we'll always allow GET, HEAD or OPTIONS requests. - if request.method in permissions.SAFE_METHODS: + if request.method in permissions.SAFE_METHODS: return True - + # Instance must have an attribute named `owner`. return obj.owner == request.user diff --git a/docs/api-guide/relations.md b/docs/api-guide/relations.md index d03a75ae5..ad981b2bb 100644 --- a/docs/api-guide/relations.md +++ b/docs/api-guide/relations.md @@ -1,4 +1,4 @@ - +source: relations.py # Serializer relations @@ -33,7 +33,7 @@ In order to explain the various types of relational fields, we'll use a couple o class Meta: unique_together = ('album', 'order') order_by = 'order' - + def __unicode__(self): return '%d: %s' % (self.order, self.title) @@ -42,10 +42,10 @@ In order to explain the various types of relational fields, we'll use a couple o `RelatedField` may be used to represent the target of the relationship using its `__unicode__` method. For example, the following serializer. - + class AlbumSerializer(serializers.ModelSerializer): tracks = serializers.RelatedField(many=True) - + class Meta: model = Album fields = ('album_name', 'artist', 'tracks') @@ -74,10 +74,10 @@ This field is read only. `PrimaryKeyRelatedField` may be used to represent the target of the relationship using its primary key. For example, the following serializer: - + class AlbumSerializer(serializers.ModelSerializer): tracks = serializers.PrimaryKeyRelatedField(many=True, read_only=True) - + class Meta: model = Album fields = ('album_name', 'artist', 'tracks') @@ -108,11 +108,11 @@ By default this field is read-write, although you can change this behavior using `HyperlinkedRelatedField` may be used to represent the target of the relationship using a hyperlink. For example, the following serializer: - + class AlbumSerializer(serializers.ModelSerializer): tracks = serializers.HyperlinkedRelatedField(many=True, read_only=True, view_name='track-detail') - + class Meta: model = Album fields = ('album_name', 'artist', 'tracks') @@ -146,11 +146,11 @@ By default this field is read-write, although you can change this behavior using `SlugRelatedField` may be used to represent the target of the relationship using a field on the target. For example, the following serializer: - + class AlbumSerializer(serializers.ModelSerializer): tracks = serializers.SlugRelatedField(many=True, read_only=True, slug_field='title') - + class Meta: model = Album fields = ('album_name', 'artist', 'tracks') @@ -222,10 +222,10 @@ For example, the following serializer: class Meta: model = Track fields = ('order', 'title') - + class AlbumSerializer(serializers.ModelSerializer): tracks = TrackSerializer(many=True) - + class Meta: model = Album fields = ('album_name', 'artist', 'tracks') @@ -262,7 +262,7 @@ For, example, we could define a relational field, to serialize a track to a cust class AlbumSerializer(serializers.ModelSerializer): tracks = TrackListingField(many=True) - + class Meta: model = Album fields = ('album_name', 'artist', 'tracks') @@ -302,7 +302,7 @@ If you have not set a related name for the reverse relationship, you'll need to class AlbumSerializer(serializers.ModelSerializer): class Meta: - fields = ('track_set', ...) + fields = ('track_set', ...) See the Django documentation on [reverse relationships][reverse-relationships] for more details. @@ -315,14 +315,14 @@ For example, given the following model for a tag, which has a generic relationsh class TaggedItem(models.Model): """ Tags arbitrary model instances using a generic relation. - + See: https://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/ """ tag_name = models.SlugField() content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() tagged_object = GenericForeignKey('content_type', 'object_id') - + def __unicode__(self): return self.tag @@ -353,7 +353,7 @@ We could define a custom field that could be used to serialize tagged instances, def to_native(self, value): """ Serialize tagged objects to a simple textual representation. - """ + """ if isinstance(value, Bookmark): return 'Bookmark: ' + value.url elif isinstance(value, Note): @@ -366,7 +366,7 @@ If you need the target of the relationship to have a nested representation, you """ Serialize bookmark instances using a bookmark serializer, and note instances using a note serializer. - """ + """ if isinstance(value, Bookmark): serializer = BookmarkSerializer(value) elif isinstance(value, Note): @@ -391,7 +391,7 @@ to ``True``. ## Advanced Hyperlinked fields -If you have very specific requirements for the style of your hyperlinked relationships you can override `HyperlinkedRelatedField`. +If you have very specific requirements for the style of your hyperlinked relationships you can override `HyperlinkedRelatedField`. There are two methods you'll need to override. @@ -411,7 +411,7 @@ May raise an `ObjectDoesNotExist` exception. ### Example -For example, if all your object URLs used both a account and a slug in the the URL to reference the object, you might create a custom field like this: +For example, if all your object URLs used both a account and a slug in the the URL to reference the object, you might create a custom field like this: class CustomHyperlinkedField(serializers.HyperlinkedRelatedField): def get_url(self, obj, view_name, request, format): diff --git a/docs/api-guide/renderers.md b/docs/api-guide/renderers.md index db7436c23..035ec1d27 100644 --- a/docs/api-guide/renderers.md +++ b/docs/api-guide/renderers.md @@ -1,4 +1,4 @@ - +source: renderers.py # Renderers @@ -115,7 +115,7 @@ The `jsonp` approach is essentially a browser hack, and is [only appropriate for ## YAMLRenderer -Renders the request data into `YAML`. +Renders the request data into `YAML`. Requires the `pyyaml` package to be installed. @@ -131,7 +131,7 @@ Note that non-ascii characters will be rendered using `\uXXXX` character escape. ## UnicodeYAMLRenderer -Renders the request data into `YAML`. +Renders the request data into `YAML`. Requires the `pyyaml` package to be installed. @@ -184,7 +184,7 @@ An example of a view that uses `TemplateHTMLRenderer`: def get(self, request, *args, **kwargs): self.object = self.get_object() return Response({'user': self.object}, template_name='user_detail.html') - + You can use `TemplateHTMLRenderer` either to return regular HTML pages using REST framework, or to return both HTML and API responses from a single endpoint. If you're building websites that use `TemplateHTMLRenderer` along with other renderer classes, you should consider listing `TemplateHTMLRenderer` as the first class in the `renderer_classes` list, so that it will be prioritised first even for browsers that send poorly formed `ACCEPT:` headers. @@ -205,7 +205,7 @@ An example of a view that uses `TemplateHTMLRenderer`: @api_view(('GET',)) @renderer_classes((StaticHTMLRenderer,)) - def simple_html_view(request): + def simple_html_view(request): data = '

Hello, world

' return Response(data) @@ -300,7 +300,7 @@ The following is an example plaintext renderer that will return a response with class PlainTextRenderer(renderers.BaseRenderer): media_type = 'text/plain' format = 'txt' - + def render(self, data, media_type=None, renderer_context=None): return data.encode(self.charset) @@ -340,7 +340,7 @@ You can do some pretty flexible things using REST framework's renderers. Some e * Provide either flat or nested representations from the same endpoint, depending on the requested media type. * Serve both regular HTML webpages, and JSON based API responses from the same endpoints. * Specify multiple types of HTML representation for API clients to use. -* Underspecify a renderer's media type, such as using `media_type = 'image/*'`, and use the `Accept` header to vary the encoding of the response. +* Underspecify a renderer's media type, such as using `media_type = 'image/*'`, and use the `Accept` header to vary the encoding of the response. ## Varying behaviour by media type diff --git a/docs/api-guide/requests.md b/docs/api-guide/requests.md index 87425ed1b..8713fa2a6 100644 --- a/docs/api-guide/requests.md +++ b/docs/api-guide/requests.md @@ -1,4 +1,4 @@ - +source: request.py # Requests @@ -105,7 +105,7 @@ REST framework supports a few browser enhancements such as browser-based `PUT`, Browser-based `PUT`, `PATCH` and `DELETE` forms are transparently supported. -For more information see the [browser enhancements documentation]. +For more information see the [browser enhancements documentation]. ## .content_type @@ -115,7 +115,7 @@ You won't typically need to directly access the request's content type, as you'l If you do need to access the content type of the request you should use the `.content_type` property in preference to using `request.META.get('HTTP_CONTENT_TYPE')`, as it provides transparent support for browser-based non-form content. -For more information see the [browser enhancements documentation]. +For more information see the [browser enhancements documentation]. ## .stream @@ -125,7 +125,7 @@ You won't typically need to directly access the request's content, as you'll nor If you do need to access the raw content directly, you should use the `.stream` property in preference to using `request.content`, as it provides transparent support for browser-based non-form content. -For more information see the [browser enhancements documentation]. +For more information see the [browser enhancements documentation]. --- diff --git a/docs/api-guide/responses.md b/docs/api-guide/responses.md index 5a42aa923..97f312710 100644 --- a/docs/api-guide/responses.md +++ b/docs/api-guide/responses.md @@ -1,4 +1,4 @@ - +source: response.py # Responses @@ -90,6 +90,6 @@ The `Response` class extends `SimpleTemplateResponse`, and all the usual attribu As with any other `TemplateResponse`, this method is called to render the serialized data of the response into the final response content. When `.render()` is called, the response content will be set to the result of calling the `.render(data, accepted_media_type, renderer_context)` method on the `accepted_renderer` instance. You won't typically need to call `.render()` yourself, as it's handled by Django's standard response cycle. - + [cite]: https://docs.djangoproject.com/en/dev/ref/template-response/ [statuscodes]: status-codes.md diff --git a/docs/api-guide/reverse.md b/docs/api-guide/reverse.md index 383eca4ce..71fb83f9e 100644 --- a/docs/api-guide/reverse.md +++ b/docs/api-guide/reverse.md @@ -1,4 +1,4 @@ - +source: reverse.py # Returning URLs @@ -30,7 +30,7 @@ You should **include the request as a keyword argument** to the function, for ex from rest_framework.reverse import reverse from rest_framework.views import APIView from django.utils.timezone import now - + class APIRootView(APIView): def get(self, request): year = now().year diff --git a/docs/api-guide/routers.md b/docs/api-guide/routers.md index 61a476b8b..080230faf 100644 --- a/docs/api-guide/routers.md +++ b/docs/api-guide/routers.md @@ -1,4 +1,4 @@ - +source: routers.py # Routers @@ -56,10 +56,10 @@ For example, given a method like this on the `UserViewSet` class: from myapp.permissions import IsAdminOrIsSelf from rest_framework.decorators import detail_route - + class UserViewSet(ModelViewSet): ... - + @detail_route(methods=['post'], permission_classes=[IsAdminOrIsSelf]) def set_password(self, request, pk=None): ... @@ -228,7 +228,7 @@ For another example of setting the `.routes` attribute, see the source code for ## 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 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. +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. diff --git a/docs/api-guide/serializers.md b/docs/api-guide/serializers.md index eeeffa136..2d0ff79a4 100644 --- a/docs/api-guide/serializers.md +++ b/docs/api-guide/serializers.md @@ -1,4 +1,4 @@ - +source: serializers.py # Serializers @@ -21,7 +21,7 @@ Let's start by creating a simple object we can use for example purposes: self.email = email self.content = content self.created = created or datetime.datetime.now() - + comment = Comment(email='leila@example.com', content='foo bar') We'll declare a serializer that we can use to serialize and deserialize `Comment` objects. @@ -45,7 +45,7 @@ Declaring a serializer looks very similar to declaring a form: instance.content = attrs.get('content', instance.content) instance.created = attrs.get('created', instance.created) return instance - return Comment(**attrs) + return Comment(**attrs) The first part of serializer class defines the fields that get serialized/deserialized. The `restore_object` method defines how fully fledged instances get created when deserializing data. @@ -83,8 +83,8 @@ If you need to customize the serialized value of a particular field, you can do These methods are essentially the reverse of `validate_` (see *Validation* below.) ## Deserializing objects - -Deserialization is similar. First we parse a stream into Python native datatypes... + +Deserialization is similar. First we parse a stream into Python native datatypes... from StringIO import StringIO from rest_framework.parsers import JSONParser @@ -174,7 +174,7 @@ To save the deserialized objects created by a serializer, call the `.save()` met The default behavior of the method is to simply call `.save()` on the deserialized object instance. You can override the default save behaviour by overriding the `.save_object(obj)` method on the serializer class. -The generic views provided by REST framework call the `.save()` method when updating or creating entities. +The generic views provided by REST framework call the `.save()` method when updating or creating entities. ## Dealing with nested objects @@ -288,12 +288,12 @@ By default the serializer class will use the `id` key on the incoming data to de slug = serializers.CharField(max_length=100) created = serializers.DateTimeField() ... # Various other fields - + def get_identity(self, data): """ This hook is required for bulk update. We need to override the default, to use the slug as the identity. - + Note that the data has not yet been validated at this point, so we need to deal gracefully with incorrect datatypes. """ @@ -361,7 +361,7 @@ The `depth` option should be set to an integer value that indicates the depth of If you want to customize the way the serialization is done (e.g. using `allow_add_remove`) you'll need to define the field yourself. -## Specifying which fields should be read-only +## Specifying which fields should be read-only 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 `read_only_fields` Meta option, like so: @@ -371,9 +371,9 @@ You may wish to specify multiple fields as read-only. Instead of adding each fi fields = ('id', 'account_name', 'users', 'created') read_only_fields = ('account_name',) -Model fields which have `editable=False` set, and `AutoField` fields will be set to read-only by default, and do not need to be added to the `read_only_fields` option. +Model fields which have `editable=False` set, and `AutoField` fields will be set to read-only by default, and do not need to be added to the `read_only_fields` option. -## Specifying which fields should be write-only +## Specifying which fields should be write-only You may wish to specify multiple fields as write-only. Instead of adding each field explicitly with the `write_only=True` attribute, you may use the `write_only_fields` Meta option, like so: @@ -387,12 +387,12 @@ You may wish to specify multiple fields as write-only. Instead of adding each f """ Instantiate a new User instance. """ - assert instance is None, 'Cannot update users with CreateUserSerializer' + assert instance is None, 'Cannot update users with CreateUserSerializer' user = User(email=attrs['email'], username=attrs['username']) user.set_password(attrs['password']) return user - -## Specifying fields explicitly + +## Specifying fields explicitly You can add extra fields to a `ModelSerializer` or override the default fields by declaring fields on the class, just as you would for a `Serializer` class. @@ -524,10 +524,10 @@ For example, if you wanted to be able to set which fields should be used by a se def __init__(self, *args, **kwargs): # Don't pass the 'fields' arg up to the superclass fields = kwargs.pop('fields', None) - + # Instantiate the superclass normally super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs) - + if fields: # Drop any fields that are not specified in the `fields` argument. allowed = set(fields) @@ -550,7 +550,7 @@ This would then allow you to do the following: ## Customising the default fields -The `field_mapping` attribute is a dictionary that maps model classes to serializer classes. Overriding the attribute will let you set a different set of default serializer classes. +The `field_mapping` attribute is a dictionary that maps model classes to serializer classes. Overriding the attribute will let you set a different set of default serializer classes. For more advanced customization than simply changing the default serializer class you can override various `get__field` methods. Doing so will allow you to customize the arguments that each serializer field is initialized with. Each of these methods may either return a field or serializer instance, or `None`. diff --git a/docs/api-guide/settings.md b/docs/api-guide/settings.md index 96d715ea2..0aa4b6a97 100644 --- a/docs/api-guide/settings.md +++ b/docs/api-guide/settings.md @@ -1,4 +1,4 @@ - +source: settings.py # Settings diff --git a/docs/api-guide/status-codes.md b/docs/api-guide/status-codes.md index 64c464349..d81e092c5 100644 --- a/docs/api-guide/status-codes.md +++ b/docs/api-guide/status-codes.md @@ -1,4 +1,4 @@ - +source: status.py # Status Codes @@ -27,7 +27,7 @@ The module also includes a set of helper functions for testing if a status code 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]. @@ -51,7 +51,7 @@ This class of status code indicates that the client's request was successfully r HTTP_205_RESET_CONTENT HTTP_206_PARTIAL_CONTENT -## Redirection - 3xx +## Redirection - 3xx This class of status code indicates that further action needs to be taken by the user agent in order to fulfill the request. diff --git a/docs/api-guide/testing.md b/docs/api-guide/testing.md index 72c339613..d059fdab5 100644 --- a/docs/api-guide/testing.md +++ b/docs/api-guide/testing.md @@ -1,4 +1,4 @@ - +source: test.py # Testing @@ -170,7 +170,7 @@ This can be a useful shortcut if you're testing the API but don't want to have t To unauthenticate subsequent requests, call `force_authenticate` setting the user and/or token to `None`. - client.force_authenticate(user=None) + client.force_authenticate(user=None) ## CSRF validation @@ -197,7 +197,7 @@ You can use any of REST framework's test case classes as you would for the regul from django.core.urlresolvers import reverse from rest_framework import status - from rest_framework.test import APITestCase + from rest_framework.test import APITestCase class AccountTests(APITestCase): def test_create_account(self): diff --git a/docs/api-guide/throttling.md b/docs/api-guide/throttling.md index 147c16ff7..3f668867c 100644 --- a/docs/api-guide/throttling.md +++ b/docs/api-guide/throttling.md @@ -1,4 +1,4 @@ - +source: throttling.py # Throttling @@ -83,7 +83,7 @@ The throttle classes provided by REST framework use Django's cache backend. You If you need to use a cache other than `'default'`, you can do so by creating a custom throttle class and setting the `cache` attribute. For example: class CustomAnonRateThrottle(AnonRateThrottle): - cache = get_cache('alternate') + cache = get_cache('alternate') You'll need to remember to also set your custom throttle class in the `'DEFAULT_THROTTLE_CLASSES'` settings key, or using the `throttle_classes` view attribute. @@ -147,15 +147,15 @@ For example, given the following views... class ContactListView(APIView): throttle_scope = 'contacts' ... - + class ContactDetailView(ApiView): throttle_scope = 'contacts' ... - class UploadView(APIView): + class UploadView(APIView): throttle_scope = 'uploads' ... - + ...and the following settings. REST_FRAMEWORK = { diff --git a/docs/api-guide/views.md b/docs/api-guide/views.md index 194a7a6b3..31c62682f 100644 --- a/docs/api-guide/views.md +++ b/docs/api-guide/views.md @@ -1,4 +1,5 @@ - +source: decorators.py + views.py # Class Based Views @@ -26,7 +27,7 @@ For example: class ListUsers(APIView): """ View to list all users in the system. - + * Requires token authentication. * Only admin users are able to access this view. """ @@ -54,7 +55,7 @@ The following attributes control the pluggable aspects of API views. ### .permission_classes -### .content_negotiation_class +### .content_negotiation_class ## API policy instantiation methods diff --git a/docs/api-guide/viewsets.md b/docs/api-guide/viewsets.md index 9030e3ee0..9249d8756 100644 --- a/docs/api-guide/viewsets.md +++ b/docs/api-guide/viewsets.md @@ -1,4 +1,4 @@ - +source: viewsets.py # ViewSets diff --git a/docs/theme/content.html b/docs/theme/content.html new file mode 100644 index 000000000..93a437ff8 --- /dev/null +++ b/docs/theme/content.html @@ -0,0 +1,11 @@ +{% if meta.source %} + + {% for filename in meta.source %} + + {{ filename }} + + {% endfor %} + +{% endif %} + +{{ content }} diff --git a/docs_theme/base.html b/docs_theme/base.html index 4ca6cd810..07582392f 100644 --- a/docs_theme/base.html +++ b/docs_theme/base.html @@ -118,7 +118,7 @@ a.fusion-poweredby {
- {{ content }} + {% include "content.html" %}