mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-25 11:04:02 +03:00
Use MkDocs meta.source to render source code links
This commit is contained in:
parent
cbb6799d2d
commit
16d442dda3
|
@ -1,4 +1,4 @@
|
|||
<a class="github" href="authentication.py"></a>
|
||||
source: authentication.py
|
||||
|
||||
# Authentication
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<a class="github" href="negotiation.py"></a>
|
||||
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.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<a class="github" href="exceptions.py"></a>
|
||||
source: exceptions.py
|
||||
|
||||
# Exceptions
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<a class="github" href="fields.py"></a>
|
||||
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`
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<a class="github" href="filters.py"></a>
|
||||
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.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<a class="github" href="urlpatterns.py"></a>
|
||||
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<pk>[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]
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<a class="github" href="mixins.py"></a>
|
||||
<a class="github" href="generics.py"></a>
|
||||
source: mixins.py
|
||||
generics.py
|
||||
|
||||
# Generic views
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<a class="github" href="pagination.py"></a>
|
||||
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.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<a class="github" href="parsers.py"></a>
|
||||
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
|
||||
[djangorestframework-camel-case]: https://github.com/vbabiy/djangorestframework-camel-case
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<a class="github" href="permissions.py"></a>
|
||||
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
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<a class="github" href="relations.py"></a>
|
||||
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):
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<a class="github" href="renderers.py"></a>
|
||||
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 = '<html><body><h1>Hello, world</h1></body></html>'
|
||||
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
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<a class="github" href="request.py"></a>
|
||||
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].
|
||||
|
||||
---
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<a class="github" href="response.py"></a>
|
||||
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
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<a class="github" href="reverse.py"></a>
|
||||
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
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<a class="github" href="routers.py"></a>
|
||||
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.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<a class="github" href="serializers.py"></a>
|
||||
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_<fieldname>` (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_type>_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`.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<a class="github" href="settings.py"></a>
|
||||
source: settings.py
|
||||
|
||||
# Settings
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<a class="github" href="status.py"></a>
|
||||
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.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<a class="github" href="test.py"></a>
|
||||
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):
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<a class="github" href="throttling.py"></a>
|
||||
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 = {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<a class="github" href="decorators.py"></a> <a class="github" href="views.py"></a>
|
||||
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
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<a class="github" href="viewsets.py"></a>
|
||||
source: viewsets.py
|
||||
|
||||
# ViewSets
|
||||
|
||||
|
|
11
docs/theme/content.html
vendored
Normal file
11
docs/theme/content.html
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
{% if meta.source %}
|
||||
|
||||
{% for filename in meta.source %}
|
||||
<a class="github" href="https://github.com/tomchristie/django-rest-framework/tree/master/rest_framework/{{ filename }}">
|
||||
<span class="label label-info">{{ filename }}</span>
|
||||
</a>
|
||||
{% endfor %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
{{ content }}
|
|
@ -118,7 +118,7 @@ a.fusion-poweredby {
|
|||
</div>
|
||||
|
||||
<div id="main-content" class="span9">
|
||||
{{ content }}
|
||||
{% include "content.html" %}
|
||||
</div><!--/span-->
|
||||
</div><!--/row-->
|
||||
</div><!--/.fluid-container-->
|
||||
|
|
Loading…
Reference in New Issue
Block a user