mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-01-27 09:44:37 +03:00
Update documentation
This commit is contained in:
parent
ccf3829d16
commit
144701c887
6
404.html
6
404.html
|
@ -277,6 +277,10 @@
|
|||
<a href="topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../../topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../../topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../../topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../../topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
@ -381,6 +385,10 @@
|
|||
<a href="#uuidfield">UUIDField</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#filepathfield">FilePathField</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#ipaddressfield">IPAddressField</a>
|
||||
</li>
|
||||
|
@ -559,6 +567,7 @@
|
|||
<h2 id="core-arguments">Core arguments</h2>
|
||||
<p>Each serializer field class constructor takes at least these arguments. Some Field classes take additional, field-specific arguments, but the following should always be accepted:</p>
|
||||
<h3 id="read_only"><code>read_only</code></h3>
|
||||
<p>Read-only fields are included in the API output, but should not be included in the input during create or update operations. Any 'read_only' fields that are incorrectly included in the serializer input will be ignored.</p>
|
||||
<p>Set this to <code>True</code> to ensure that the field is used when serializing a representation, but is not used when creating or updating an instance during deserialization.</p>
|
||||
<p>Defaults to <code>False</code></p>
|
||||
<h3 id="write_only"><code>write_only</code></h3>
|
||||
|
@ -662,6 +671,17 @@ color_channel = serializers.ChoiceField(
|
|||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h2 id="filepathfield">FilePathField</h2>
|
||||
<p>A field whose choices are limited to the filenames in a certain directory on the filesystem</p>
|
||||
<p>Corresponds to <code>django.forms.fields.FilePathField</code>.</p>
|
||||
<p><strong>Signature:</strong> <code>FilePathField(path, match=None, recursive=False, allow_files=True, allow_folders=False, required=None, **kwargs)</code></p>
|
||||
<ul>
|
||||
<li><code>path</code> - The absolute filesystem path to a directory from which this FilePathField should get its choice.</li>
|
||||
<li><code>match</code> - A regular expression, as a string, that FilePathField will use to filter filenames.</li>
|
||||
<li><code>recursive</code> - Specifies whether all subdirectories of path should be included. Default is <code>False</code>.</li>
|
||||
<li><code>allow_files</code> - Specifies whether files in the specified location should be included. Default is <code>True</code>. Either this or <code>allow_folders</code> must be <code>True</code>.</li>
|
||||
<li><code>allow_folders</code> - Specifies whether folders in the specified location should be included. Default is <code>False</code>. Either this or <code>allow_files</code> must be <code>True</code>.</li>
|
||||
</ul>
|
||||
<h2 id="ipaddressfield">IPAddressField</h2>
|
||||
<p>A field that ensures the input is a valid IPv4 or IPv6 string.</p>
|
||||
<p>Corresponds to <code>django.forms.fields.IPAddressField</code> and <code>django.forms.fields.GenericIPAddressField</code>.</p>
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../../topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../../topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../../topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
@ -445,6 +449,10 @@
|
|||
<a href="#django-rest-framework-bulk">Django REST Framework bulk</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#django-rest-multiple-models">Django Rest Multiple Models</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -611,12 +619,19 @@ class UserList(generics.ListCreateAPIView):
|
|||
instance = serializer.save()
|
||||
send_email_confirmation(user=self.request.user, modified=instance)
|
||||
</code></pre>
|
||||
<p>You can also use these hooks to provide additional validation, by raising a <code>ValidationError()</code>. This can be useful if you need some validation logic to apply at the point of database save. For example:</p>
|
||||
<pre><code>def perform_create(self, serializer):
|
||||
queryset = SignupRequest.objects.filter(user=self.request.user)
|
||||
if queryset.exists():
|
||||
raise ValidationError('You have already signed up')
|
||||
serializer.save(user=self.request.user)
|
||||
</code></pre>
|
||||
<p><strong>Note</strong>: These methods replace the old-style version 2.x <code>pre_save</code>, <code>post_save</code>, <code>pre_delete</code> and <code>post_delete</code> methods, which are no longer available.</p>
|
||||
<p><strong>Other methods</strong>:</p>
|
||||
<p>You won't typically need to override the following methods, although you might need to call into them if you're writing custom views using <code>GenericAPIView</code>.</p>
|
||||
<ul>
|
||||
<li><code>get_serializer_context(self)</code> - Returns a dictionary containing any extra context that should be supplied to the serializer. Defaults to including <code>'request'</code>, <code>'view'</code> and <code>'format'</code> keys.</li>
|
||||
<li><code>get_serializer(self, instance=None, data=None, files=None, many=False, partial=False, allow_add_remove=False)</code> - Returns a serializer instance.</li>
|
||||
<li><code>get_serializer(self, instance=None, data=None, many=False, partial=False)</code> - Returns a serializer instance.</li>
|
||||
<li><code>get_paginated_response(self, data)</code> - Returns a paginated style <code>Response</code> object.</li>
|
||||
<li><code>paginate_queryset(self, queryset)</code> - Paginate a queryset if required, either returning a page object, or <code>None</code> if pagination is not configured for this view.</li>
|
||||
<li><code>filter_queryset(self, queryset)</code> - Given a queryset, filter it with whichever filter backends are in use, returning a new queryset.</li>
|
||||
|
@ -731,6 +746,8 @@ class BaseRetrieveUpdateDestroyView(MultipleFieldLookupMixin,
|
|||
<p>The following third party packages provide additional generic view implementations.</p>
|
||||
<h2 id="django-rest-framework-bulk">Django REST Framework bulk</h2>
|
||||
<p>The <a href="https://github.com/miki725/django-rest-framework-bulk">django-rest-framework-bulk package</a> implements generic view mixins as well as some common concrete generic views to allow to apply bulk operations via API requests.</p>
|
||||
<h2 id="django-rest-multiple-models">Django Rest Multiple Models</h2>
|
||||
<p><a href="https://github.com/Axiologue/DjangoRestMultipleModels">Django Rest Multiple Models</a> provides a generic view (and mixin) for sending multiple serialized models and/or querysets via a single API request.</p>
|
||||
|
||||
|
||||
</div> <!--/span-->
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../../topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
@ -449,6 +453,11 @@ def schema(self, request):
|
|||
'description': view.get_view_description()
|
||||
}
|
||||
</code></pre>
|
||||
<p>Then configure your settings to use this custom class:</p>
|
||||
<pre><code>REST_FRAMEWORK = {
|
||||
'DEFAULT_METADATA_CLASS': 'myproject.apps.core.MinimalMetadata'
|
||||
}
|
||||
</code></pre>
|
||||
|
||||
|
||||
</div> <!--/span-->
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../../topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
@ -605,11 +609,11 @@ class StandardResultsSetPagination(PageNumberPagination):
|
|||
previous_url = self.get_previous_link()
|
||||
|
||||
if next_url is not None and previous_url is not None:
|
||||
link = '<{next_url}; rel="next">, <{previous_url}; rel="prev">'
|
||||
link = '<{next_url}>; rel="next", <{previous_url}>; rel="prev"'
|
||||
elif next_url is not None:
|
||||
link = '<{next_url}; rel="next">'
|
||||
link = '<{next_url}>; rel="next"'
|
||||
elif previous_url is not None:
|
||||
link = '<{previous_url}; rel="prev">'
|
||||
link = '<{previous_url}>; rel="prev"'
|
||||
else:
|
||||
link = ''
|
||||
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../../topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
@ -522,17 +526,16 @@ def example_view(request, format=None):
|
|||
<h2 id="example">Example</h2>
|
||||
<p>The following is an example plaintext parser that will populate the <code>request.data</code> property with a string representing the body of the request.</p>
|
||||
<pre><code>class PlainTextParser(BaseParser):
|
||||
"""
|
||||
Plain text parser.
|
||||
"""
|
||||
|
||||
media_type = 'text/plain'
|
||||
|
||||
def parse(self, stream, media_type=None, parser_context=None):
|
||||
"""
|
||||
Simply return a string representing the body of the request.
|
||||
Plain text parser.
|
||||
"""
|
||||
return stream.read()
|
||||
media_type = 'text/plain'
|
||||
|
||||
def parse(self, stream, media_type=None, parser_context=None):
|
||||
"""
|
||||
Simply return a string representing the body of the request.
|
||||
"""
|
||||
return stream.read()
|
||||
</code></pre>
|
||||
<hr />
|
||||
<h1 id="third-party-packages">Third party packages</h1>
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../../topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
@ -403,6 +407,10 @@
|
|||
<a href="#rest-condition">REST Condition</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#dry-rest-permissions">DRY Rest Permissions</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -486,7 +494,11 @@ class ExampleView(APIView):
|
|||
return Response(content)
|
||||
</code></pre>
|
||||
<p>Or, if you're using the <code>@api_view</code> decorator with function based views.</p>
|
||||
<pre><code>@api_view('GET')
|
||||
<pre><code>from rest_framework.decorators import api_view, permission_classes
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.response import Response
|
||||
|
||||
@api_view('GET')
|
||||
@permission_classes((IsAuthenticated, ))
|
||||
def example_view(request, format=None):
|
||||
content = {
|
||||
|
@ -553,6 +565,15 @@ else:
|
|||
<hr />
|
||||
<p><strong>Note</strong>: The instance-level <code>has_object_permission</code> method will only be called if the view-level <code>has_permission</code> checks have already passed. Also note that in order for the instance-level checks to run, the view code should explicitly call <code>.check_object_permissions(request, obj)</code>. If you are using the generic views then this will be handled for you by default.</p>
|
||||
<hr />
|
||||
<p>Custom permissions will raise a <code>PermissionDenied</code> exception if the test fails. To change the error message associated with the exception, implement a <code>message</code> attribute directly on your custom permission. Otherwise the <code>default_detail</code> attribute from <code>PermissionDenied</code> will be used.</p>
|
||||
<pre><code>from rest_framework import permissions
|
||||
|
||||
class CustomerAccessPermission(permissions.BasePermission):
|
||||
message = 'Adding customers not allowed.'
|
||||
|
||||
def has_permission(self, request, view):
|
||||
...
|
||||
</code></pre>
|
||||
<h2 id="examples">Examples</h2>
|
||||
<p>The following is an example of a permission class that checks the incoming request's IP address against a blacklist, and denies the request if the IP has been blacklisted.</p>
|
||||
<pre><code>from rest_framework import permissions
|
||||
|
@ -592,6 +613,8 @@ class BlacklistPermission(permissions.BasePermission):
|
|||
<p>The <a href="https://github.com/niwibe/djangorestframework-composed-permissions">Composed Permissions</a> package provides a simple way to define complex and multi-depth (with logic operators) permission objects, using small and reusable components.</p>
|
||||
<h2 id="rest-condition">REST Condition</h2>
|
||||
<p>The <a href="https://github.com/caxap/rest_condition">REST Condition</a> package is another extension for building complex permissions in a simple and convenient way. The extension allows you to combine permissions with logical operators.</p>
|
||||
<h2 id="dry-rest-permissions">DRY Rest Permissions</h2>
|
||||
<p>The <a href="https://github.com/Helioscene/dry-rest-permissions">DRY Rest Permissions</a> package provides the ability to define different permissions for individual default and custom actions. This package is made for apps with permissions that are derived from relationships defined in the app's data model. It also supports permission checks being returned to a client app through the API's serializer. Additionally it supports adding permissions to the default and custom list actions to restrict the data they retrive per user.</p>
|
||||
|
||||
|
||||
</div> <!--/span-->
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../../topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
@ -374,6 +378,12 @@
|
|||
</li>
|
||||
|
||||
|
||||
<li class="main">
|
||||
<a href="#writable-nested-serializers">Writable nested serializers</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
<li class="main">
|
||||
<a href="#custom-relational-fields">Custom relational fields</a>
|
||||
</li>
|
||||
|
@ -384,6 +394,16 @@
|
|||
</li>
|
||||
|
||||
|
||||
<li class="main">
|
||||
<a href="#custom-hyperlinked-fields">Custom hyperlinked fields</a>
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
<a href="#example_2">Example</a>
|
||||
</li>
|
||||
|
||||
|
||||
<li class="main">
|
||||
<a href="#further-notes">Further notes</a>
|
||||
</li>
|
||||
|
@ -405,10 +425,6 @@
|
|||
<a href="#manytomanyfields-with-a-through-model">ManyToManyFields with a Through Model</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#advanced-hyperlinked-fields">Advanced Hyperlinked fields</a>
|
||||
</li>
|
||||
|
||||
|
||||
<li class="main">
|
||||
<a href="#third-party-packages">Third Party Packages</a>
|
||||
|
@ -561,6 +577,11 @@ class Track(models.Model):
|
|||
}
|
||||
</code></pre>
|
||||
<p>By default this field is read-write, although you can change this behavior using the <code>read_only</code> flag.</p>
|
||||
<hr />
|
||||
<p><strong>Note</strong>: This field is designed for objects that map to a URL that accepts a single URL keyword argument, as set using the <code>lookup_field</code> and <code>lookup_url_kwarg</code> arguments.</p>
|
||||
<p>This is suitable for URLs that contain a single primary key or slug argument as part of the URL.</p>
|
||||
<p>If you require more complex hyperlinked representation you'll need to customize the field, as described in the <a href="#custom-hyperlinked-fields">custom hyperlinked fields</a> section, below.</p>
|
||||
<hr />
|
||||
<p><strong>Arguments</strong>:</p>
|
||||
<ul>
|
||||
<li><code>view_name</code> - The view name that should be used as the target of the relationship. If you're using <a href="http://www.django-rest-framework.org/api-guide/routers#defaultrouter">the standard router classes</a> this will be a string with the format <code><modelname>-detail</code>. <strong>required</strong>.</li>
|
||||
|
@ -649,17 +670,62 @@ class AlbumSerializer(serializers.ModelSerializer):
|
|||
fields = ('album_name', 'artist', 'tracks')
|
||||
</code></pre>
|
||||
<p>Would serialize to a nested representation like this:</p>
|
||||
<pre><code>{
|
||||
<pre><code>>>> album = Album.objects.create(album_name="The Grey Album", artist='Danger Mouse')
|
||||
>>> Track.objects.create(album=album, order=1, title='Public Service Announcement', duration=245)
|
||||
<Track: Track object>
|
||||
>>> Track.objects.create(album=album, order=2, title='What More Can I Say', duration=264)
|
||||
<Track: Track object>
|
||||
>>> Track.objects.create(album=album, order=3, title='Encore', duration=159)
|
||||
<Track: Track object>
|
||||
>>> serializer = AlbumSerializer(instance=album)
|
||||
>>> serializer.data
|
||||
{
|
||||
'album_name': 'The Grey Album',
|
||||
'artist': 'Danger Mouse',
|
||||
'tracks': [
|
||||
{'order': 1, 'title': 'Public Service Announcement'},
|
||||
{'order': 2, 'title': 'What More Can I Say'},
|
||||
{'order': 3, 'title': 'Encore'},
|
||||
{'order': 1, 'title': 'Public Service Announcement', 'duration': 245},
|
||||
{'order': 2, 'title': 'What More Can I Say', 'duration': 264},
|
||||
{'order': 3, 'title': 'Encore', 'duration': 159},
|
||||
...
|
||||
],
|
||||
}
|
||||
</code></pre>
|
||||
<h1 id="writable-nested-serializers">Writable nested serializers</h1>
|
||||
<p>Be default nested serializers are read-only. If you want to to support write-operations to a nested serializer field you'll need to create either or both of the <code>create()</code> and/or <code>update()</code> methods, in order to explicitly specify how the child relationships should be saved.</p>
|
||||
<pre><code>class TrackSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Track
|
||||
fields = ('order', 'title')
|
||||
|
||||
class AlbumSerializer(serializers.ModelSerializer):
|
||||
tracks = TrackSerializer(many=True)
|
||||
|
||||
class Meta:
|
||||
model = Album
|
||||
fields = ('album_name', 'artist', 'tracks')
|
||||
|
||||
def create(self, validated_data):
|
||||
tracks_data = validated_data.pop('tracks')
|
||||
album = Album.objects.create(**validated_data)
|
||||
for track_data in tracks_data:
|
||||
Track.objects.create(album=album, **track_data)
|
||||
return album
|
||||
|
||||
>>> data = {
|
||||
'album_name': 'The Grey Album',
|
||||
'artist': 'Danger Mouse',
|
||||
'tracks': [
|
||||
{'order': 1, 'title': 'Public Service Announcement', 'duration': 245},
|
||||
{'order': 2, 'title': 'What More Can I Say', 'duration': 264},
|
||||
{'order': 3, 'title': 'Encore', 'duration': 159},
|
||||
],
|
||||
}
|
||||
>>> serializer = AlbumSerializer(data=data)
|
||||
>>> serializer.is_valid()
|
||||
True
|
||||
>>> serializer.save()
|
||||
<Album: Album object>
|
||||
</code></pre>
|
||||
<h1 id="custom-relational-fields">Custom relational fields</h1>
|
||||
<p>To implement a custom relational field, you should override <code>RelatedField</code>, and implement the <code>.to_representation(self, value)</code> method. This method takes the target of the field as the <code>value</code> argument, and should return the representation that should be used to serialize the target. The <code>value</code> argument will typically be a model instance.</p>
|
||||
<p>If you want to implement a read-write relational field, you must also implement the <code>.to_internal_value(self, data)</code> method.</p>
|
||||
|
@ -692,6 +758,48 @@ class AlbumSerializer(serializers.ModelSerializer):
|
|||
}
|
||||
</code></pre>
|
||||
<hr />
|
||||
<h1 id="custom-hyperlinked-fields">Custom hyperlinked fields</h1>
|
||||
<p>In some cases you may need to customize the behavior of a hyperlinked field, in order to represent URLs that require more than a single lookup field.</p>
|
||||
<p>You can achieve this by overriding <code>HyperlinkedRelatedField</code>. There are two methods that may be overridden:</p>
|
||||
<p><strong>get_url(self, obj, view_name, request, format)</strong></p>
|
||||
<p>The <code>get_url</code> method is used to map the object instance to its URL representation.</p>
|
||||
<p>May raise a <code>NoReverseMatch</code> if the <code>view_name</code> and <code>lookup_field</code>
|
||||
attributes are not configured to correctly match the URL conf.</p>
|
||||
<p><strong>get_object(self, queryset, view_name, view_args, view_kwargs)</strong></p>
|
||||
<p>If you want to support a writable hyperlinked field then you'll also want to override <code>get_object</code>, in order to map incoming URLs back to the object they represent. For read-only hyperlinked fields there is no need to override this method.</p>
|
||||
<p>The return value of this method should the object that corresponds to the matched URL conf arguments.</p>
|
||||
<p>May raise an <code>ObjectDoesNotExist</code> exception.</p>
|
||||
<h2 id="example_2">Example</h2>
|
||||
<p>Say we have a URL for a customer object that takes two keyword arguments, like so:</p>
|
||||
<pre><code>/api/<organization_slug>/customers/<customer_pk>/
|
||||
</code></pre>
|
||||
<p>This cannot be represented with the default implementation, which accepts only a single lookup field.</p>
|
||||
<p>In this case we'd need to override <code>HyperlinkedRelatedField</code> to get the behavior we want:</p>
|
||||
<pre><code>from rest_framework import serializers
|
||||
from rest_framework.reverse import reverse
|
||||
|
||||
class CustomerHyperlink(serializers.HyperlinkedRelatedField):
|
||||
# We define these as class attributes, so we don't need to pass them as arguments.
|
||||
view_name = 'customer-detail'
|
||||
queryset = Customer.objects.all()
|
||||
|
||||
def get_url(self, obj, view_name, request, format):
|
||||
url_kwargs = {
|
||||
'organization_slug': obj.organization.slug,
|
||||
'customer_pk': obj.pk
|
||||
}
|
||||
return reverse(view_name, url_kwargs, request=request, format=format)
|
||||
|
||||
def get_object(self, view_name, view_args, view_kwargs):
|
||||
lookup_kwargs = {
|
||||
'organization__slug': view_kwargs['organization_slug'],
|
||||
'pk': view_kwargs['customer_pk']
|
||||
}
|
||||
return self.get_queryset().get(**lookup_kwargs)
|
||||
</code></pre>
|
||||
<p>Note that if you wanted to use this style together with the generic views then you'd also need to override <code>.get_object</code> on the view in order to get the correct lookup behavior.</p>
|
||||
<p>Generally we recommend a flat style for API representations where possible, but the nested URL style can also be reasonable when used in moderation.</p>
|
||||
<hr />
|
||||
<h1 id="further-notes">Further notes</h1>
|
||||
<h2 id="the-queryset-argument">The <code>queryset</code> argument</h2>
|
||||
<p>The <code>queryset</code> argument is only ever required for <em>writable</em> relationship field, in which case it is used for performing the model instance lookup, that maps from the primitive user input, into a model instance.</p>
|
||||
|
@ -787,28 +895,6 @@ class Note(models.Model):
|
|||
<p>If you explicitly specify a relational field pointing to a
|
||||
<code>ManyToManyField</code> with a through model, be sure to set <code>read_only</code>
|
||||
to <code>True</code>.</p>
|
||||
<h2 id="advanced-hyperlinked-fields">Advanced Hyperlinked fields</h2>
|
||||
<p>If you have very specific requirements for the style of your hyperlinked relationships you can override <code>HyperlinkedRelatedField</code>.</p>
|
||||
<p>There are two methods you'll need to override.</p>
|
||||
<h4 id="get_urlself-obj-view_name-request-format">get_url(self, obj, view_name, request, format)</h4>
|
||||
<p>This method should return the URL that corresponds to the given object.</p>
|
||||
<p>May raise a <code>NoReverseMatch</code> if the <code>view_name</code> and <code>lookup_field</code>
|
||||
attributes are not configured to correctly match the URL conf.</p>
|
||||
<h4 id="get_objectself-queryset-view_name-view_args-view_kwargs">get_object(self, queryset, view_name, view_args, view_kwargs)</h4>
|
||||
<p>This method should the object that corresponds to the matched URL conf arguments.</p>
|
||||
<p>May raise an <code>ObjectDoesNotExist</code> exception.</p>
|
||||
<h3 id="example_2">Example</h3>
|
||||
<p>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:</p>
|
||||
<pre><code>class CustomHyperlinkedField(serializers.HyperlinkedRelatedField):
|
||||
def get_url(self, obj, view_name, request, format):
|
||||
kwargs = {'account': obj.account, 'slug': obj.slug}
|
||||
return reverse(view_name, kwargs=kwargs, request=request, format=format)
|
||||
|
||||
def get_object(self, queryset, view_name, view_args, view_kwargs):
|
||||
account = view_kwargs['account']
|
||||
slug = view_kwargs['slug']
|
||||
return queryset.get(account=account, slug=slug)
|
||||
</code></pre>
|
||||
<hr />
|
||||
<h1 id="third-party-packages">Third Party Packages</h1>
|
||||
<p>The following third party packages are also available.</p>
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../../topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
@ -364,11 +368,15 @@
|
|||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#htmlformrenderer">HTMLFormRenderer</a>
|
||||
<a href="#browsableapirenderer">BrowsableAPIRenderer</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#browsableapirenderer">BrowsableAPIRenderer</a>
|
||||
<a href="#adminrenderer">AdminRenderer</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#htmlformrenderer">HTMLFormRenderer</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
@ -590,25 +598,36 @@ def simple_html_view(request):
|
|||
<p><strong>.format</strong>: <code>'.html'</code></p>
|
||||
<p><strong>.charset</strong>: <code>utf-8</code></p>
|
||||
<p>See also: <code>TemplateHTMLRenderer</code></p>
|
||||
<h2 id="htmlformrenderer">HTMLFormRenderer</h2>
|
||||
<p>Renders data returned by a serializer into an HTML form. The output of this renderer does not include the enclosing <code><form></code> tags or an submit actions, as you'll probably need those to include the desired method and URL. Also note that the <code>HTMLFormRenderer</code> does not yet support including field error messages.</p>
|
||||
<p>Note that the template used by the <code>HTMLFormRenderer</code> class, and the context submitted to it <strong>may be subject to change</strong>. If you need to use this renderer class it is advised that you either make a local copy of the class and templates, or follow the release note on REST framework upgrades closely.</p>
|
||||
<p><strong>.media_type</strong>: <code>text/html</code></p>
|
||||
<p><strong>.format</strong>: <code>'.form'</code></p>
|
||||
<p><strong>.charset</strong>: <code>utf-8</code></p>
|
||||
<p><strong>.template</strong>: <code>'rest_framework/form.html'</code></p>
|
||||
<h2 id="browsableapirenderer">BrowsableAPIRenderer</h2>
|
||||
<p>Renders data into HTML for the Browsable API. This renderer will determine which other renderer would have been given highest priority, and use that to display an API style response within the HTML page.</p>
|
||||
<p>Renders data into HTML for the Browsable API:</p>
|
||||
<p><img alt="The BrowsableAPIRenderer" src="../../img/quickstart.png" /></p>
|
||||
<p>This renderer will determine which other renderer would have been given highest priority, and use that to display an API style response within the HTML page.</p>
|
||||
<p><strong>.media_type</strong>: <code>text/html</code></p>
|
||||
<p><strong>.format</strong>: <code>'.api'</code></p>
|
||||
<p><strong>.charset</strong>: <code>utf-8</code></p>
|
||||
<p><strong>.template</strong>: <code>'rest_framework/api.html'</code></p>
|
||||
<h4 id="customizing-browsableapirenderer">Customizing BrowsableAPIRenderer</h4>
|
||||
<p>By default the response content will be rendered with the highest priority renderer apart from <code>BrowseableAPIRenderer</code>. If you need to customize this behavior, for example to use HTML as the default return format, but use JSON in the browsable API, you can do so by overriding the <code>get_default_renderer()</code> method. For example:</p>
|
||||
<p>By default the response content will be rendered with the highest priority renderer apart from <code>BrowsableAPIRenderer</code>. If you need to customize this behavior, for example to use HTML as the default return format, but use JSON in the browsable API, you can do so by overriding the <code>get_default_renderer()</code> method. For example:</p>
|
||||
<pre><code>class CustomBrowsableAPIRenderer(BrowsableAPIRenderer):
|
||||
def get_default_renderer(self, view):
|
||||
return JSONRenderer()
|
||||
</code></pre>
|
||||
<h2 id="adminrenderer">AdminRenderer</h2>
|
||||
<p>Renders data into HTML for an admin-like display:</p>
|
||||
<p><img alt="The AdminRender view" src="../../img/admin.png" /></p>
|
||||
<p>This renderer is suitable for CRUD-style web APIs that should also present a user-friendly interface for managing the data.</p>
|
||||
<p>Note that views that have nested or list serializers for their input won't work well with the <code>AdminRenderer</code>, as the HTML forms are unable to properly support them.</p>
|
||||
<p><strong>.media_type</strong>: <code>text/html</code></p>
|
||||
<p><strong>.format</strong>: <code>'.admin'</code></p>
|
||||
<p><strong>.charset</strong>: <code>utf-8</code></p>
|
||||
<p><strong>.template</strong>: <code>'rest_framework/admin.html'</code></p>
|
||||
<h2 id="htmlformrenderer">HTMLFormRenderer</h2>
|
||||
<p>Renders data returned by a serializer into an HTML form. The output of this renderer does not include the enclosing <code><form></code> tags or an submit actions, as you'll probably need those to include the desired method and URL. Also note that the <code>HTMLFormRenderer</code> does not yet support including field error messages.</p>
|
||||
<p><strong>Note</strong>: The <code>HTMLFormRenderer</code> class is intended for internal use with the browsable API and admin interface. It should not be considered a fully documented or stable API. The template used by the <code>HTMLFormRenderer</code> class, and the context submitted to it <strong>may be subject to change</strong>. If you need to use this renderer class it is advised that you either make a local copy of the class and templates, or follow the release note on REST framework upgrades closely.</p>
|
||||
<p><strong>.media_type</strong>: <code>text/html</code></p>
|
||||
<p><strong>.format</strong>: <code>'.form'</code></p>
|
||||
<p><strong>.charset</strong>: <code>utf-8</code></p>
|
||||
<p><strong>.template</strong>: <code>'rest_framework/form.html'</code></p>
|
||||
<h2 id="multipartrenderer">MultiPartRenderer</h2>
|
||||
<p>This renderer is used for rendering HTML multipart form data. <strong>It is not suitable as a response renderer</strong>, but is instead used for creating test requests, using REST framework's <a href="../testing/">test client and test request factory</a>.</p>
|
||||
<p><strong>.media_type</strong>: <code>multipart/form-data; boundary=BoUnDaRyStRiNg</code></p>
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../../topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../../topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../../topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../../topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../../topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
@ -963,7 +967,7 @@ AccountSerializer():
|
|||
<p>Typically we would recommend <em>not</em> using inheritance on inner Meta classes, but instead declaring all options explicitly.</p>
|
||||
<h2 id="customizing-field-mappings">Customizing field mappings</h2>
|
||||
<p>The ModelSerializer class also exposes an API that you can override in order to alter how serializer fields are automatically determined when instantiating the serializer.</p>
|
||||
<p>Normally if a <code>ModelSerializer</code> does not generate the fields you need by default the you should either add them to the class explicitly, or simply use a regular <code>Serializer</code> class instead. However in some cases you may want to create a new base class that defines how the serializer fields are created for any given model.</p>
|
||||
<p>Normally if a <code>ModelSerializer</code> does not generate the fields you need by default then you should either add them to the class explicitly, or simply use a regular <code>Serializer</code> class instead. However in some cases you may want to create a new base class that defines how the serializer fields are created for any given model.</p>
|
||||
<h3 id="serializer_field_mapping"><code>.serializer_field_mapping</code></h3>
|
||||
<p>A mapping of Django model classes to REST framework serializer classes. You can override this mapping to alter the default serializer classes that should be used for each model class.</p>
|
||||
<h3 id="serializer_related_field"><code>.serializer_related_field</code></h3>
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../../topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
@ -480,6 +484,10 @@ If set to <code>None</code> then generic filtering is disabled.</p>
|
|||
<p>The default page size to use for pagination. If set to <code>None</code>, pagination is disabled by default.</p>
|
||||
<p>Default: <code>None</code></p>
|
||||
<h4 id="paginate_by_param">PAGINATE_BY_PARAM</h4>
|
||||
<hr />
|
||||
<p><strong>This setting is pending deprecation.</strong></p>
|
||||
<p>See the pagination documentation for further guidance on <a href="../pagination/#modifying-the-pagination-style">setting the pagination style</a>.</p>
|
||||
<hr />
|
||||
<p>The name of a query parameter, which can be used by the client to override the default page size to use for pagination. If set to <code>None</code>, clients may not override the default page size.</p>
|
||||
<p>For example, given the following settings:</p>
|
||||
<pre><code>REST_FRAMEWORK = {
|
||||
|
@ -492,6 +500,10 @@ If set to <code>None</code> then generic filtering is disabled.</p>
|
|||
</code></pre>
|
||||
<p>Default: <code>None</code></p>
|
||||
<h4 id="max_paginate_by">MAX_PAGINATE_BY</h4>
|
||||
<hr />
|
||||
<p><strong>This setting is pending deprecation.</strong></p>
|
||||
<p>See the pagination documentation for further guidance on <a href="../pagination/#modifying-the-pagination-style">setting the pagination style</a>.</p>
|
||||
<hr />
|
||||
<p>The maximum page size to allow when the page size is specified by the client. If set to <code>None</code>, then no maximum limit is applied.</p>
|
||||
<p>For example, given the following settings:</p>
|
||||
<pre><code>REST_FRAMEWORK = {
|
||||
|
@ -567,6 +579,7 @@ If set to <code>None</code> then generic filtering is disabled.</p>
|
|||
<p>Default: <code>'accept'</code></p>
|
||||
<h4 id="url_format_override">URL_FORMAT_OVERRIDE</h4>
|
||||
<p>The name of a URL parameter that may be used to override the default <code>Accept</code> header based content negotiation.</p>
|
||||
<p>If the value of this setting is <code>None</code> then URL format overloading will be disabled.</p>
|
||||
<p>Default: <code>'format'</code></p>
|
||||
<hr />
|
||||
<h2 id="date-and-time-formatting">Date and time formatting</h2>
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../../topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../../topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../../topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../../topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
@ -556,7 +560,7 @@ It has two required arguments, and a single optional <code>messages</code> argum
|
|||
</code></pre>
|
||||
<h2 id="class-based">Class based</h2>
|
||||
<p>To write a class based validator, use the <code>__call__</code> method. Class based validators are useful as they allow you to parameterize and reuse behavior.</p>
|
||||
<pre><code>class MultipleOf:
|
||||
<pre><code>class MultipleOf(object):
|
||||
def __init__(self, base):
|
||||
self.base = base
|
||||
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../../topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
@ -447,7 +451,7 @@ reverse('bookings-list', request=request)
|
|||
<p>The following settings keys are also used to control versioning:</p>
|
||||
<ul>
|
||||
<li><code>DEFAULT_VERSION</code>. The value that should be used for <code>request.version</code> when no versioning information is present. Defaults to <code>None</code>.</li>
|
||||
<li><code>ALLOWED_VERSIONS</code>. If set, this value will restrict the set of versions that may be returned by the versioning scheme, and will raise an error if the provided version if not in this set. Defaults to <code>None</code>.</li>
|
||||
<li><code>ALLOWED_VERSIONS</code>. If set, this value will restrict the set of versions that may be returned by the versioning scheme, and will raise an error if the provided version if not in this set. Note that the value used for the <code>DEFAULT_VERSION</code> setting is always considered to be part of the <code>ALLOWED_VERSIONS</code> set. Defaults to <code>None</code>.</li>
|
||||
<li><code>VERSION_PARAMETER</code>. The string that should used for any versioning parameters, such as in the media type or URL query parameters. Defaults to <code>'version'</code>.</li>
|
||||
</ul>
|
||||
<p>You can also set your versioning class plus those three values on a per-view or a per-viewset basis by defining your own versioning scheme and using the <code>default_version</code>, <code>allowed_versions</code> and <code>version_param</code> class variables. For example, if you want to use <code>URLPathVersioning</code>:</p>
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../../topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../../topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
|
|
@ -176,7 +176,7 @@ body{
|
|||
}
|
||||
|
||||
#main-content h3, #main-content h4, #main-content h5 {
|
||||
font-weight: 500;
|
||||
font-weight: 300;
|
||||
margin-top: 15px
|
||||
}
|
||||
|
||||
|
|
BIN
img/admin.png
Normal file
BIN
img/admin.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 55 KiB |
|
@ -277,6 +277,10 @@
|
|||
<a href="topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
@ -460,7 +464,7 @@
|
|||
<p>REST framework requires the following:</p>
|
||||
<ul>
|
||||
<li>Python (2.6.5+, 2.7, 3.2, 3.3, 3.4)</li>
|
||||
<li>Django (1.4.11+, 1.5.6+, 1.6.3+, 1.7+, 1.8)</li>
|
||||
<li>Django (1.5.6+, 1.6.3+, 1.7+, 1.8)</li>
|
||||
</ul>
|
||||
<p>The following packages are optional:</p>
|
||||
<ul>
|
||||
|
@ -588,6 +592,7 @@ urlpatterns = [
|
|||
<li><a href="topics/project-management/">Project management</a></li>
|
||||
<li><a href="topics/3.0-announcement/">3.0 Announcement</a></li>
|
||||
<li><a href="topics/3.1-announcement/">3.1 Announcement</a></li>
|
||||
<li><a href="topics/3.2-announcement/">3.2 Announcement</a></li>
|
||||
<li><a href="topics/kickstarter-announcement/">Kickstarter Announcement</a></li>
|
||||
<li><a href="topics/release-notes/">Release Notes</a></li>
|
||||
</ul>
|
||||
|
|
56
js/theme.js
56
js/theme.js
|
@ -1,35 +1,35 @@
|
|||
function getSearchTerm()
|
||||
{
|
||||
var sPageURL = window.location.search.substring(1);
|
||||
var sURLVariables = sPageURL.split('&');
|
||||
for (var i = 0; i < sURLVariables.length; i++)
|
||||
{
|
||||
var sParameterName = sURLVariables[i].split('=');
|
||||
if (sParameterName[0] == 'q')
|
||||
{
|
||||
return sParameterName[1];
|
||||
}
|
||||
var getSearchTerm = function() {
|
||||
var sPageURL = window.location.search.substring(1);
|
||||
var sURLVariables = sPageURL.split('&');
|
||||
for (var i = 0; i < sURLVariables.length; i++) {
|
||||
var sParameterName = sURLVariables[i].split('=');
|
||||
if (sParameterName[0] === 'q') {
|
||||
return sParameterName[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var initilizeSearch = function() {
|
||||
require.config({ baseUrl: '/mkdocs/js' });
|
||||
require(['search']);
|
||||
};
|
||||
|
||||
$(function() {
|
||||
var searchTerm = getSearchTerm(),
|
||||
$searchModal = $('#mkdocs_search_modal'),
|
||||
$searchQuery = $searchModal.find('#mkdocs-search-query'),
|
||||
$searchResults = $searchModal.find('#mkdocs-search-results');
|
||||
|
||||
var initialise_search = function(){
|
||||
require.config({"baseUrl":"/mkdocs/js"});
|
||||
require(["search",]);
|
||||
}
|
||||
$('pre code').parent().addClass('prettyprint well');
|
||||
|
||||
var search_term = getSearchTerm();
|
||||
if(search_term){
|
||||
$('#mkdocs_search_modal').modal();
|
||||
}
|
||||
|
||||
$('pre code').parent().addClass('prettyprint well');
|
||||
|
||||
$(document).on("submit", "#mkdocs_search_modal form", function (e) {
|
||||
$("#mkdocs-search-results").html("Searching...");
|
||||
initialise_search();
|
||||
return false;
|
||||
});
|
||||
if (searchTerm) {
|
||||
$searchQuery.val(searchTerm);
|
||||
$searchResults.text('Searching...');
|
||||
$searchModal.modal();
|
||||
}
|
||||
|
||||
$searchModal.on('shown', function() {
|
||||
$searchQuery.focus();
|
||||
initilizeSearch();
|
||||
});
|
||||
});
|
||||
|
|
File diff suppressed because one or more lines are too long
100
sitemap.xml
100
sitemap.xml
|
@ -4,7 +4,7 @@
|
|||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
|
@ -13,43 +13,43 @@
|
|||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//tutorial/quickstart/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//tutorial/1-serialization/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//tutorial/2-requests-and-responses/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//tutorial/3-class-based-views/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//tutorial/4-authentication-and-permissions/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//tutorial/5-relationships-and-hyperlinked-apis/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//tutorial/6-viewsets-and-routers/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
|
@ -59,157 +59,157 @@
|
|||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//api-guide/requests/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//api-guide/responses/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//api-guide/views/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//api-guide/generic-views/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//api-guide/viewsets/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//api-guide/routers/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//api-guide/parsers/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//api-guide/renderers/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//api-guide/serializers/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//api-guide/fields/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//api-guide/relations/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//api-guide/validators/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//api-guide/authentication/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//api-guide/permissions/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//api-guide/throttling/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//api-guide/filtering/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//api-guide/pagination/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//api-guide/versioning/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//api-guide/content-negotiation/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//api-guide/metadata/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//api-guide/format-suffixes/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//api-guide/reverse/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//api-guide/exceptions/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//api-guide/status-codes/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//api-guide/testing/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//api-guide/settings/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
|
@ -219,79 +219,85 @@
|
|||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//topics/documenting-your-api/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//topics/internationalization/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//topics/ajax-csrf-cors/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//topics/browser-enhancements/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//topics/browsable-api/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//topics/rest-hypermedia-hateoas/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//topics/third-party-resources/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//topics/contributing/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//topics/project-management/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//topics/3.0-announcement/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//topics/3.1-announcement/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//topics/3.2-announcement/</loc>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//topics/kickstarter-announcement/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>http://www.django-rest-framework.org//topics/release-notes/</loc>
|
||||
<lastmod>2015-06-23</lastmod>
|
||||
<lastmod>2015-08-06</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
@ -1111,7 +1115,7 @@ amount = serializers.DecimalField(
|
|||
<li>The serializer <code>ChoiceField</code> does not currently display nested choices, as was the case in 2.4. This will be address as part of 3.1.</li>
|
||||
<li>Due to the new templated form rendering, the 'widget' option is no longer valid. This means there's no easy way of using third party "autocomplete" widgets for rendering select inputs that contain a large number of choices. You'll either need to use a regular select or a plain text input. We may consider addressing this in 3.1 or 3.2 if there's sufficient demand.</li>
|
||||
<li>Some of the default validation error messages were rewritten and might no longer be pre-translated. You can still <a href="https://docs.djangoproject.com/en/dev/topics/i18n/translation/#localization-how-to-create-language-files">create language files with Django</a> if you wish to localize them.</li>
|
||||
<li><code>APIException</code> subclasses could previously take could previously take any arbitrary type in the <code>detail</code> argument. These exceptions now use translatable text strings, and as a result call <code>force_text</code> on the <code>detail</code> argument, which <em>must be a string</em>. If you need complex arguments to an <code>APIException</code> class, you should subclass it and override the <code>__init__()</code> method. Typically you'll instead want to use a custom exception handler to provide for non-standard error responses.</li>
|
||||
<li><code>APIException</code> subclasses could previously take any arbitrary type in the <code>detail</code> argument. These exceptions now use translatable text strings, and as a result call <code>force_text</code> on the <code>detail</code> argument, which <em>must be a string</em>. If you need complex arguments to an <code>APIException</code> class, you should subclass it and override the <code>__init__()</code> method. Typically you'll instead want to use a custom exception handler to provide for non-standard error responses.</li>
|
||||
</ul>
|
||||
<hr />
|
||||
<h2 id="whats-coming-next">What's coming next</h2>
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
<div class="navbar-inner">
|
||||
<div class="container-fluid">
|
||||
<a class="repo-link btn btn-primary btn-small" href="https://github.com/tomchristie/django-rest-framework/tree/master">GitHub</a>
|
||||
<a class="repo-link btn btn-inverse btn-small " rel="prev" href="../kickstarter-announcement/">
|
||||
<a class="repo-link btn btn-inverse btn-small " rel="prev" href="../3.2-announcement/">
|
||||
Next <i class="icon-arrow-right icon-white"></i>
|
||||
</a>
|
||||
<a class="repo-link btn btn-inverse btn-small " rel="next" href="../3.0-announcement/">
|
||||
|
@ -277,6 +277,10 @@
|
|||
<a href="./">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
|
496
topics/3.2-announcement/index.html
Normal file
496
topics/3.2-announcement/index.html
Normal file
|
@ -0,0 +1,496 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta charset="utf-8">
|
||||
<title>3.2 Announcement - Django REST framework</title>
|
||||
<link href="../../img/favicon.ico" rel="icon" type="image/x-icon">
|
||||
<link rel="canonical" href="http://www.django-rest-framework.org/topics/3.2-announcement/" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Django, API, REST, 3.2 Announcement">
|
||||
<meta name="author" content="Tom Christie">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="../../css/prettify.css" rel="stylesheet">
|
||||
<link href="../../css/bootstrap.css" rel="stylesheet">
|
||||
<link href="../../css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="../../css/default.css" rel="stylesheet">
|
||||
|
||||
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<script type="text/javascript">
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-18852272-2']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
|
||||
(function() {
|
||||
var ga = document.createElement('script');
|
||||
ga.type = 'text/javascript';
|
||||
ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
</script>
|
||||
|
||||
<style>
|
||||
span.fusion-wrap a {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
color: black;
|
||||
}
|
||||
a.fusion-poweredby {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
div.promo {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="prettyPrint()" class="-page">
|
||||
|
||||
<div class="wrapper">
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container-fluid">
|
||||
<a class="repo-link btn btn-primary btn-small" href="https://github.com/tomchristie/django-rest-framework/tree/master">GitHub</a>
|
||||
<a class="repo-link btn btn-inverse btn-small " rel="prev" href="../kickstarter-announcement/">
|
||||
Next <i class="icon-arrow-right icon-white"></i>
|
||||
</a>
|
||||
<a class="repo-link btn btn-inverse btn-small " rel="next" href="../3.1-announcement/">
|
||||
<i class="icon-arrow-left icon-white"></i> Previous
|
||||
</a>
|
||||
<a id="search_modal_show" class="repo-link btn btn-inverse btn-small" href="#mkdocs_search_modal" data-toggle="modal" data-target="#mkdocs_search_modal"><i class="icon-search icon-white"></i> Search</a>
|
||||
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</a>
|
||||
<a class="brand" href="http://www.django-rest-framework.org">Django REST framework</a>
|
||||
<div class="nav-collapse collapse">
|
||||
|
||||
<!-- Main navigation -->
|
||||
<ul class="nav navbar-nav">
|
||||
|
||||
<li >
|
||||
<a href="../..">Home</a>
|
||||
</li>
|
||||
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Tutorial <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/quickstart/">Quickstart</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/1-serialization/">1 - Serialization</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/2-requests-and-responses/">2 - Requests and responses</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/3-class-based-views/">3 - Class based views</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/4-authentication-and-permissions/">4 - Authentication and permissions</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/5-relationships-and-hyperlinked-apis/">5 - Relationships and hyperlinked APIs</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">API Guide <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
|
||||
<li >
|
||||
<a href="../../api-guide/requests/">Requests</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../api-guide/responses/">Responses</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../api-guide/views/">Views</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../api-guide/generic-views/">Generic views</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../api-guide/viewsets/">Viewsets</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../api-guide/routers/">Routers</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../api-guide/parsers/">Parsers</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../api-guide/renderers/">Renderers</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../api-guide/serializers/">Serializers</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../api-guide/fields/">Serializer fields</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../api-guide/relations/">Serializer relations</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../api-guide/validators/">Validators</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../api-guide/authentication/">Authentication</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../api-guide/permissions/">Permissions</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../api-guide/throttling/">Throttling</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../api-guide/filtering/">Filtering</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../api-guide/pagination/">Pagination</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../api-guide/versioning/">Versioning</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../api-guide/content-negotiation/">Content negotiation</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../api-guide/metadata/">Metadata</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../api-guide/format-suffixes/">Format suffixes</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../api-guide/reverse/">Returning URLs</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../api-guide/exceptions/">Exceptions</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../api-guide/status-codes/">Status codes</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../api-guide/testing/">Testing</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../api-guide/settings/">Settings</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="dropdown active">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Topics <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
|
||||
<li >
|
||||
<a href="../documenting-your-api/">Documenting your API</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../internationalization/">Internationalization</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../ajax-csrf-cors/">AJAX, CSRF & CORS</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../browser-enhancements/">Browser Enhancements</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../browsable-api/">The Browsable API</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../rest-hypermedia-hateoas/">REST, Hypermedia & HATEOAS</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../third-party-resources/">Third Party Resources</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../contributing/">Contributing to REST framework</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../project-management/">Project management</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../3.0-announcement/">3.0 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li class="active" >
|
||||
<a href="./">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../release-notes/">Release Notes</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
<!--/.nav-collapse -->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="body-content">
|
||||
<div class="container-fluid">
|
||||
<!-- Search Modal -->
|
||||
<div id="mkdocs_search_modal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3 id="myModalLabel">Documentation search</h3>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
</form>
|
||||
<div id="mkdocs-search-results"></div>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row-fluid">
|
||||
<div class="span3">
|
||||
<div id="table-of-contents">
|
||||
<ul class="nav nav-list side-nav well sidebar-nav-fixed">
|
||||
|
||||
|
||||
|
||||
<li class="main">
|
||||
<a href="#django-rest-framework-32">Django REST framework 3.2</a>
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
<a href="#adminrenderer">AdminRenderer</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#deprecations">Deprecations</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#modifications-to-list-behaviors">Modifications to list behaviors</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#whats-next">What's next?</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="main-content" class="span9">
|
||||
|
||||
|
||||
|
||||
<h1 id="django-rest-framework-32">Django REST framework 3.2</h1>
|
||||
<p>The 3.2 release is the first version to include an admin interface for the browsable API.</p>
|
||||
<p><img alt="The AdminRenderer" src="../../img/admin.png" /></p>
|
||||
<p>This interface is intended to act as a more user-friendly interface to the API. It can be used either as a replacement to the existing <code>BrowsableAPIRenderer</code>, or used together with it, allowing you to switch between the two styles as required.</p>
|
||||
<p>We've also fixed a huge number of issues, and made numerous cleanups and improvements.</p>
|
||||
<p>Over the course of the 3.1.x series we've <a href="https://github.com/tomchristie/django-rest-framework/issues?utf8=%E2%9C%93&q=closed%3A%3E2015-03-05">resolved nearly 600 tickets</a> on our GitHub issue tracker. This means we're currently running at a rate of <strong>closing around 100 issues or pull requests per month</strong>.</p>
|
||||
<p>None of this would have been possible without the support of our wonderful Kickstarter backers. If you're looking for a job in Django development we'd strongly recommend taking <a href="http://www.django-rest-framework.org/topics/kickstarter-announcement/#sponsors">a look through our sponsors</a> and finding out who's hiring.</p>
|
||||
<h2 id="adminrenderer">AdminRenderer</h2>
|
||||
<p>To include <code>AdminRenderer</code> simply add it to your settings:</p>
|
||||
<pre><code>REST_FRAMEWORK = {
|
||||
'DEFAULT_RENDERER_CLASSES': [
|
||||
'rest_framework.renderers.JSONRenderer',
|
||||
'rest_framework.renderers.AdminRenderer',
|
||||
'rest_framework.renderers.BrowsableAPIRenderer'
|
||||
],
|
||||
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
|
||||
'PAGE_SIZE': 100
|
||||
}
|
||||
</code></pre>
|
||||
<p>There are some limitations to the <code>AdminRenderer</code>, in particular it is not yet able to handle list or dictionary inputs, as we do not have any HTML form fields that support those.</p>
|
||||
<p>Also note that this is an initial release and we do not yet have a public API for modifying the behavior or documentation on overriding the templates.</p>
|
||||
<p>The idea is to get this released to users early, so we can start getting feedback and release a more fully featured version in 3.3.</p>
|
||||
<h2 id="deprecations">Deprecations</h2>
|
||||
<p>There are no new deprecations in 3.2, although a number of existing deprecations have now escalated in line with our deprecation policy.</p>
|
||||
<ul>
|
||||
<li><code>request.DATA</code> was put on the deprecation path in 3.0. It has now been removed and its usage will result in an error. Use the more pythonic style of <code>request.data</code> instead.</li>
|
||||
<li><code>request.FILES</code> was put on the deprecation path in 3.0. It has now been removed and its usage will result in an error. Use the more pythonic style of <code>request.files</code> instead.</li>
|
||||
<li><code>request.QUERY_PARAMS</code> was put on the deprecation path in 3.0. It has now been removed and its usage will result in an error. Use the more pythonic style of <code>request.query_params</code> instead.</li>
|
||||
<li>The following <code>ModelSerializer.Meta</code> options have now been removed: <code>write_only_fields</code>, <code>view_name</code>, <code>lookup_field</code>. Use the more general <code>extra_kwargs</code> option instead.</li>
|
||||
</ul>
|
||||
<p>The following pagination view attributes and settings have been moved into attributes on the pagination class since 3.1. Their usage was formerly in 'pending deprecation', and has now escalated to 'deprecated'. They will continue to function but will raise errors.</p>
|
||||
<ul>
|
||||
<li><code>view.paginate_by</code> - Use <code>paginator.page_size</code> instead.</li>
|
||||
<li><code>view.page_query_param</code> - Use <code>paginator.page_query_param</code> instead.</li>
|
||||
<li><code>view.paginate_by_param</code> - Use <code>paginator.page_size_query_param</code> instead.</li>
|
||||
<li><code>view.max_paginate_by</code> - Use <code>paginator.max_page_size</code> instead.</li>
|
||||
<li><code>settings.PAGINATE_BY</code> - Use <code>paginator.page_size</code> instead.</li>
|
||||
<li><code>settings.PAGINATE_BY_PARAM</code> - Use <code>paginator.page_size_query_param</code> instead.</li>
|
||||
<li><code>settings.MAX_PAGINATE_BY</code> - Use <code>max_page_size</code> instead.</li>
|
||||
</ul>
|
||||
<h2 id="modifications-to-list-behaviors">Modifications to list behaviors</h2>
|
||||
<p>There are a couple of bug fixes that are worth calling out as they introduce differing behavior.</p>
|
||||
<p>These are a little subtle and probably won't affect most users, but are worth understanding before upgrading your project.</p>
|
||||
<h3 id="manytomany-fields-and-blanktrue">ManyToMany fields and blank=True</h3>
|
||||
<p>We've now added an <code>allow_empty</code> argument, which can be used with <code>ListSerializer</code>, or with <code>many=True</code> relationships. This is <code>True</code> by default, but can be set to <code>False</code> if you want to disallow empty lists as valid input.</p>
|
||||
<p>As a follow-up to this we are now able to properly mirror the behavior of Django's <code>ModelForm</code> with respect to how many-to-many fields are validated.</p>
|
||||
<p>Previously a many-to-many field on a model would map to a serializer field that would allow either empty or non-empty list inputs. Now, a many-to-many field will map to a serializer field that requires at least one input, unless the model field has <code>blank=True</code> set.</p>
|
||||
<p>Here's what the mapping looks like in practice:</p>
|
||||
<ul>
|
||||
<li><code>models.ManyToManyField()</code> → <code>serializers.PrimaryKeyRelatedField(many=True, allow_empty=False)</code></li>
|
||||
<li><code>models.ManyToManyField(blank=True)</code> → <code>serializers.PrimaryKeyRelatedField(many=True)</code></li>
|
||||
</ul>
|
||||
<p>The upshot is this: If you have many to many fields in your models, then make sure you've included the argument <code>blank=True</code> if you want to allow empty inputs in the equivalent <code>ModelSerializer</code> fields.</p>
|
||||
<h3 id="list-fields-and-allow_null">List fields and allow_null</h3>
|
||||
<p>When using <code>allow_null</code> with <code>ListField</code> or a nested <code>mant=True</code> serializer the previous behavior was to allow <code>null</code> values as items in the list. The behavior is now to allow <code>null</code> values instead of the list.</p>
|
||||
<p>For example, take the following field:</p>
|
||||
<pre><code>NestedSerializer(many=True, allow_null=True)
|
||||
</code></pre>
|
||||
<p>Previously the validation behavior would be:</p>
|
||||
<ul>
|
||||
<li><code>[{…}, null, {…}]</code> is <strong>valid</strong>.</li>
|
||||
<li><code>null</code> is <strong>invalid</strong>.</li>
|
||||
</ul>
|
||||
<p>Our validation behavior as of 3.2.0 is now:</p>
|
||||
<ul>
|
||||
<li><code>[{…}, null, {…}]</code> is <strong>invalid</strong>.</li>
|
||||
<li><code>null</code> is <strong>valid</strong>.</li>
|
||||
</ul>
|
||||
<p>If you want to allow <code>null</code> child items, you'll need to instead specify <code>allow_null</code> on the child class, using an explicit <code>ListField</code> instead of <code>many=True</code>. For example:</p>
|
||||
<pre><code>ListField(child=NestedSerializer(allow_null=True))
|
||||
</code></pre>
|
||||
<h2 id="whats-next">What's next?</h2>
|
||||
<p>The 3.3 release is currently planned for the start of October, and will be the last Kickstarter-funded release.</p>
|
||||
<p>This release is planned to include:</p>
|
||||
<ul>
|
||||
<li>Search and filtering controls in the browsable API and admin interface.</li>
|
||||
<li>Improvements and public API for the admin interface.</li>
|
||||
<li>Improvements and public API for our templated HTML forms and fields.</li>
|
||||
<li>Nested object and list support in HTML forms.</li>
|
||||
</ul>
|
||||
<p>Thanks once again to all our sponsors and supporters.</p>
|
||||
|
||||
|
||||
</div> <!--/span-->
|
||||
</div> <!--/row-->
|
||||
</div> <!--/.fluid-container-->
|
||||
</div> <!--/.body content-->
|
||||
<div id="push"></div>
|
||||
</div> <!--/.wrapper -->
|
||||
|
||||
<footer class="span12">
|
||||
<p>Documentation built with <a href="http://www.mkdocs.org/">MkDocs</a>.</a>
|
||||
</p>
|
||||
</footer>
|
||||
|
||||
<!-- Le javascript
|
||||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="../../js/jquery-1.8.1-min.js"></script>
|
||||
<script src="../../js/prettify-1.0.js"></script>
|
||||
<script src="../../js/bootstrap-2.1.1-min.js"></script>
|
||||
<script>var base_url = '../..';</script>
|
||||
<script src="../../mkdocs/js/require.js"></script>
|
||||
<script src="../../js/theme.js"></script>
|
||||
|
||||
<script>
|
||||
var shiftWindow = function() {
|
||||
scrollBy(0, -50)
|
||||
};
|
||||
|
||||
if (location.hash) shiftWindow();
|
||||
window.addEventListener("hashchange", shiftWindow);
|
||||
|
||||
$('.dropdown-menu').on('click touchstart', function(event) {
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
// Dynamically force sidenav/dropdown to no higher than browser window
|
||||
$('.side-nav, .dropdown-menu').css('max-height', window.innerHeight - 130);
|
||||
|
||||
$(function() {
|
||||
$(window).resize(function() {
|
||||
$('.side-nav, .dropdown-menu').css('max-height', window.innerHeight - 130);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
@ -409,7 +413,6 @@
|
|||
<li><code>bootstrap_navbar_variant</code> - CSS class for the navbar.</li>
|
||||
<li><code>branding</code> - Branding section of the navbar, see <a href="http://getbootstrap.com/2.3.2/components.html#navbar">Bootstrap components</a>.</li>
|
||||
<li><code>breadcrumbs</code> - Links showing resource nesting, allowing the user to go back up the resources. It's recommended to preserve these, but they can be overridden using the breadcrumbs block.</li>
|
||||
<li><code>footer</code> - Any copyright notices or similar footer materials can go here (by default right-aligned).</li>
|
||||
<li><code>script</code> - JavaScript files for the page.</li>
|
||||
<li><code>style</code> - CSS stylesheets for the page.</li>
|
||||
<li><code>title</code> - Title of the page.</li>
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
<a class="repo-link btn btn-inverse btn-small " rel="prev" href="../release-notes/">
|
||||
Next <i class="icon-arrow-right icon-white"></i>
|
||||
</a>
|
||||
<a class="repo-link btn btn-inverse btn-small " rel="next" href="../3.1-announcement/">
|
||||
<a class="repo-link btn btn-inverse btn-small " rel="next" href="../3.2-announcement/">
|
||||
<i class="icon-arrow-left icon-white"></i> Previous
|
||||
</a>
|
||||
<a id="search_modal_show" class="repo-link btn btn-inverse btn-small" href="#mkdocs_search_modal" data-toggle="modal" data-target="#mkdocs_search_modal"><i class="icon-search icon-white"></i> Search</a>
|
||||
|
@ -277,6 +277,10 @@
|
|||
<a href="../3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li class="active" >
|
||||
<a href="./">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
@ -345,6 +349,10 @@
|
|||
<a href="#upgrading">Upgrading</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#32x-series">3.2.x series</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#31x-series">3.1.x series</a>
|
||||
</li>
|
||||
|
@ -397,6 +405,41 @@
|
|||
<pre><code>pip freeze | grep djangorestframework
|
||||
</code></pre>
|
||||
<hr />
|
||||
<h2 id="32x-series">3.2.x series</h2>
|
||||
<h3 id="320">3.2.0</h3>
|
||||
<p><strong>Date</strong>: <a href="https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.2.0+Release%22">6th August 2015</a>.</p>
|
||||
<ul>
|
||||
<li>Add <code>AdminRenderer</code>. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2926">#2926</a>)</li>
|
||||
<li>Add <code>FilePathField</code>. (<a href="https://github.com/tomchristie/django-rest-framework/issues/1854">#1854</a>)</li>
|
||||
<li>Add <code>allow_empty</code> to <code>ListField</code>. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2250">#2250</a>)</li>
|
||||
<li>Support django-guardian 1.3. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3165">#3165</a>)</li>
|
||||
<li>Support grouped choices. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3225">#3225</a>)</li>
|
||||
<li>Support error forms in browsable API. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3024">#3024</a>)</li>
|
||||
<li>Allow permission classes to customize the error message. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2539">#2539</a>)</li>
|
||||
<li>Support <code>source=<method></code> on hyperlinked fields. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2690">#2690</a>)</li>
|
||||
<li><code>ListField(allow_null=True)</code> now allows null as the list value, not null items in the list. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2766">#2766</a>)</li>
|
||||
<li><code>ManyToMany()</code> maps to <code>allow_empty=False</code>, <code>ManyToMany(blank=True)</code> maps to <code>allow_empty=True</code>. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2804">#2804</a>)</li>
|
||||
<li>Support custom serialization styles for primary key fields. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2789">#2789</a>)</li>
|
||||
<li><code>OPTIONS</code> requests support nested representations. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2915">#2915</a>)</li>
|
||||
<li>Set <code>view.action == "metadata"</code> for viewsets with <code>OPTIONS</code> requests. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3115">#3115</a>)</li>
|
||||
<li>Support <code>allow_blank</code> on <code>UUIDField</code>. ([#3130][gh#3130])</li>
|
||||
<li>Do not display view docstrings with 401 or 403 response codes. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3216">#3216</a>)</li>
|
||||
<li>Resolve Django 1.8 deprecation warnings. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2886">#2886</a>)</li>
|
||||
<li>Fix for <code>DecimalField</code> validation. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3139">#3139</a>)</li>
|
||||
<li>Fix behavior of <code>allow_blank=False</code> when used with <code>trim_whitespace=True</code>. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2712">#2712</a>)</li>
|
||||
<li>Fix issue with some field combinations incorrectly mapping to an invalid <code>allow_blank</code> argument. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3011">#3011</a>)</li>
|
||||
<li>Fix for output representations with prefetches and modified querysets. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2704">#2704</a>, <a href="https://github.com/tomchristie/django-rest-framework/issues/2727">#2727</a>)</li>
|
||||
<li>Fix assertion error when CursorPagination is provided with certains invalid query parameters. (#2920)<a href="https://github.com/tomchristie/django-rest-framework/issues/2920">gh2920</a>.</li>
|
||||
<li>Fix <code>UnicodeDecodeError</code> when invalid characters included in header with <code>TokenAuthentication</code>. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2928">#2928</a>)</li>
|
||||
<li>Fix transaction rollbacks with <code>@non_atomic_requests</code> decorator. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3016">#3016</a>)</li>
|
||||
<li>Fix duplicate results issue with Oracle databases using <code>SearchFilter</code>. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2935">#2935</a>)</li>
|
||||
<li>Fix checkbox alignment and rendering in browsable API forms. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2783">#2783</a>)</li>
|
||||
<li>Fix for unsaved file objects which should use <code>"url": null</code> in the representation. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2759">#2759</a>)</li>
|
||||
<li>Fix field value rendering in browsable API. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2416">#2416</a>)</li>
|
||||
<li>Fix <code>HStoreField</code> to include <code>allow_blank=True</code> in <code>DictField</code> mapping. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2659">#2659</a>)</li>
|
||||
<li>Numerous other cleanups, improvements to error messaging, private API & minor fixes.</li>
|
||||
</ul>
|
||||
<hr />
|
||||
<h2 id="31x-series">3.1.x series</h2>
|
||||
<h3 id="313">3.1.3</h3>
|
||||
<p><strong>Date</strong>: <a href="https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.1.3+Release%22">4th June 2015</a>.</p>
|
||||
|
@ -550,6 +593,7 @@
|
|||
<!-- 3.1.1 -->
|
||||
<!-- 3.1.2 -->
|
||||
<!-- 3.1.3 --></p>
|
||||
<!-- 3.2.0 -->
|
||||
|
||||
|
||||
</div> <!--/span-->
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
@ -381,7 +385,7 @@ the Design of Network-based Software Architectures</a>.</li>
|
|||
<p>It is self evident that REST framework makes it possible to build Hypermedia APIs. The browsable API that it offers is built on HTML - the hypermedia language of the web.</p>
|
||||
<p>REST framework also includes <a href="../../api-guide/serializers/">serialization</a> and <a href="../../api-guide/parsers/">parser</a>/<a href="../../api-guide/renderers/">renderer</a> components that make it easy to build appropriate media types, <a href="../../api-guide/fields/">hyperlinked relations</a> for building well-connected systems, and great support for <a href="../../api-guide/content-negotiation/">content negotiation</a>.</p>
|
||||
<h2 id="what-rest-framework-doesnt-provide">What REST framework doesn't provide.</h2>
|
||||
<p>What REST framework doesn't do is give you is machine readable hypermedia formats such as <a href="http://stateless.co/hal_specification.html">HAL</a>, <a href="http://www.amundsen.com/media-types/collection/">Collection+JSON</a>, <a href="http://jsonapi.org/">JSON API</a> or HTML <a href="http://microformats.org/wiki/Main_Page">microformats</a> by default, or the ability to auto-magically create fully HATEOAS style APIs that include hypermedia-based form descriptions and semantically labelled hyperlinks. Doing so would involve making opinionated choices about API design that should really remain outside of the framework's scope.</p>
|
||||
<p>What REST framework doesn't do is give you machine readable hypermedia formats such as <a href="http://stateless.co/hal_specification.html">HAL</a>, <a href="http://www.amundsen.com/media-types/collection/">Collection+JSON</a>, <a href="http://jsonapi.org/">JSON API</a> or HTML <a href="http://microformats.org/wiki/Main_Page">microformats</a> by default, or the ability to auto-magically create fully HATEOAS style APIs that include hypermedia-based form descriptions and semantically labelled hyperlinks. Doing so would involve making opinionated choices about API design that should really remain outside of the framework's scope.</p>
|
||||
|
||||
|
||||
</div> <!--/span-->
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
@ -471,7 +475,7 @@ You probably want to also tag the version now:
|
|||
<h4 id="adding-to-the-django-rest-framework-grid">Adding to the Django REST framework grid</h4>
|
||||
<p>We suggest adding your package to the <a href="https://www.djangopackages.com/grids/g/django-rest-framework/">REST Framework</a> grid on Django Packages.</p>
|
||||
<h4 id="adding-to-the-django-rest-framework-docs">Adding to the Django REST framework docs</h4>
|
||||
<p>Create a <a href="https://github.com/tomchristie/django-rest-framework/compare">Pull Request</a> or <a href="https://github.com/tomchristie/django-rest-framework/issues/new">Issue</a> on GitHub, and we'll add a link to it from the main REST framework documentation. You can add your package under <strong>Third party packages</strong> of the API Guide section that best applies, like <a href="../../api-guide/authentication/">Authentication</a> or <a href="../../api-guide/permissions/">Permissions</a>. You can also link your package under the [Third Party Resources][third-party-resources] section.</p>
|
||||
<p>Create a <a href="https://github.com/tomchristie/django-rest-framework/compare">Pull Request</a> or <a href="https://github.com/tomchristie/django-rest-framework/issues/new">Issue</a> on GitHub, and we'll add a link to it from the main REST framework documentation. You can add your package under <strong>Third party packages</strong> of the API Guide section that best applies, like <a href="../../api-guide/authentication/">Authentication</a> or <a href="../../api-guide/permissions/">Permissions</a>. You can also link your package under the <a href="../../topics/third-party-resources/#existing-third-party-packages">Third Party Resources</a> section.</p>
|
||||
<h4 id="announce-on-the-discussion-group">Announce on the discussion group.</h4>
|
||||
<p>You can also let others know about your package through the <a href="https://groups.google.com/forum/#!forum/django-rest-framework">discussion group</a>.</p>
|
||||
<h2 id="existing-third-party-packages">Existing Third Party Packages</h2>
|
||||
|
@ -494,6 +498,7 @@ You probably want to also tag the version now:
|
|||
<li><a href="https://github.com/kevin-brown/drf-any-permissions">drf-any-permissions</a> - Provides alternative permission handling.</li>
|
||||
<li><a href="https://github.com/niwibe/djangorestframework-composed-permissions">djangorestframework-composed-permissions</a> - Provides a simple way to define complex permissions.</li>
|
||||
<li><a href="https://github.com/caxap/rest_condition">rest_condition</a> - Another extension for building complex permissions in a simple and convenient way.</li>
|
||||
<li><a href="https://github.com/Helioscene/dry-rest-permissions">dry-rest-permissions</a> - Provides a simple way to define permissions for individual api actions.</li>
|
||||
</ul>
|
||||
<h3 id="serializers">Serializers</h3>
|
||||
<ul>
|
||||
|
@ -510,6 +515,7 @@ You probably want to also tag the version now:
|
|||
<h3 id="views">Views</h3>
|
||||
<ul>
|
||||
<li><a href="https://github.com/miki725/django-rest-framework-bulk">djangorestframework-bulk</a> - Implements generic view mixins as well as some common concrete generic views to allow to apply bulk operations via API requests.</li>
|
||||
<li><a href="https://github.com/Axiologue/DjangoRestMultipleModels">django-rest-multiple-models</a> - Provides a generic view (and mixin) for sending multiple serialized models and/or querysets via a single API request.</li>
|
||||
</ul>
|
||||
<h3 id="routers">Routers</h3>
|
||||
<ul>
|
||||
|
@ -536,11 +542,12 @@ You probably want to also tag the version now:
|
|||
<li><a href="https://github.com/fredkingham/django_rest_model_hyperlink_serializers_project">djangorestrelationalhyperlink</a> - A hyperlinked serialiser that can can be used to alter relationships via hyperlinks, but otherwise like a hyperlink model serializer.</li>
|
||||
<li><a href="https://github.com/marcgibbons/django-rest-swagger">django-rest-swagger</a> - An API documentation generator for Swagger UI.</li>
|
||||
<li><a href="https://github.com/eofs/django-rest-framework-proxy">django-rest-framework-proxy</a> - Proxy to redirect incoming request to another API server.</li>
|
||||
<li><a href="https://github.com/AppsFuel/gaiarestframework">gaiarestframework</a> - Utils for django-rest-framewok</li>
|
||||
<li><a href="https://github.com/AppsFuel/gaiarestframework">gaiarestframework</a> - Utils for django-rest-framework</li>
|
||||
<li><a href="https://github.com/chibisov/drf-extensions">drf-extensions</a> - A collection of custom extensions</li>
|
||||
<li><a href="https://github.com/dustinfarris/ember-django-adapter">ember-django-adapter</a> - An adapter for working with Ember.js</li>
|
||||
<li><a href="https://github.com/WGBH/django-versatileimagefield">django-versatileimagefield</a> - Provides a drop-in replacement for Django's stock <code>ImageField</code> that makes it easy to serve images in multiple sizes/renditions from a single field. For DRF-specific implementation docs, <a href="http://django-versatileimagefield.readthedocs.org/en/latest/drf_integration.html">click here</a>.</li>
|
||||
<li><a href="https://github.com/aschn/drf-tracking">drf-tracking</a> - Utilities to track requests to DRF API views.</li>
|
||||
<li><a href="https://github.com/dealertrack/django-rest-framework-braces">django-rest-framework-braces</a> - Collection of utilities for working with Django Rest Framework. The most notable ones are <a href="https://django-rest-framework-braces.readthedocs.org/en/latest/overview.html#formserializer">FormSerializer</a> and <a href="https://django-rest-framework-braces.readthedocs.org/en/latest/overview.html#serializerform">SerializerForm</a>, which are adapters between DRF serializers and Django forms.</li>
|
||||
</ul>
|
||||
<h2 id="other-resources">Other Resources</h2>
|
||||
<h3 id="tutorials">Tutorials</h3>
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../../topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
@ -454,8 +458,7 @@ python manage.py migrate
|
|||
</code></pre>
|
||||
<h2 id="creating-a-serializer-class">Creating a Serializer class</h2>
|
||||
<p>The first thing we need to get started on our Web API is to provide a way of serializing and deserializing the snippet instances into representations such as <code>json</code>. We can do this by declaring serializers that work very similar to Django's forms. Create a file in the <code>snippets</code> directory named <code>serializers.py</code> and add the following.</p>
|
||||
<pre><code>from django.forms import widgets
|
||||
from rest_framework import serializers
|
||||
<pre><code>from rest_framework import serializers
|
||||
from snippets.models import Snippet, LANGUAGE_CHOICES, STYLE_CHOICES
|
||||
|
||||
|
||||
|
@ -652,7 +655,7 @@ urlpatterns = [
|
|||
Validating models...
|
||||
|
||||
0 errors found
|
||||
Django version 1.4.3, using settings 'tutorial.settings'
|
||||
Django version 1.8.3, using settings 'tutorial.settings'
|
||||
Development server is running at http://127.0.0.1:8000/
|
||||
Quit the server with CONTROL-C.
|
||||
</code></pre>
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../../topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
@ -464,7 +468,7 @@ def snippet_detail(request, pk):
|
|||
<pre><code>def snippet_detail(request, pk, format=None):
|
||||
</code></pre>
|
||||
<p>Now update the <code>urls.py</code> file slightly, to append a set of <code>format_suffix_patterns</code> in addition to the existing URLs.</p>
|
||||
<pre><code>from django.conf.urls import patterns, url
|
||||
<pre><code>from django.conf.urls import url
|
||||
from rest_framework.urlpatterns import format_suffix_patterns
|
||||
from snippets import views
|
||||
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../../topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../../topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../../topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../../topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
|
|
@ -277,6 +277,10 @@
|
|||
<a href="../../topics/3.1-announcement/">3.1 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/3.2-announcement/">3.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
@ -308,7 +312,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form role="form">
|
||||
<form role="form" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
|
||||
</div>
|
||||
|
@ -427,7 +431,7 @@ class UserViewSet(viewsets.ModelViewSet):
|
|||
"""
|
||||
API endpoint that allows users to be viewed or edited.
|
||||
"""
|
||||
queryset = User.objects.all()
|
||||
queryset = User.objects.all().order_by('-date_joined')
|
||||
serializer_class = UserSerializer
|
||||
|
||||
|
||||
|
@ -440,7 +444,6 @@ class GroupViewSet(viewsets.ModelViewSet):
|
|||
</code></pre>
|
||||
<p>Rather than write multiple views we're grouping together all the common behavior into classes called <code>ViewSets</code>.</p>
|
||||
<p>We can easily break these down into individual views if we need to, but using viewsets keeps the view logic nicely organized as well as being very concise.</p>
|
||||
<p>For trivial cases you can simply set a <code>model</code> attribute on the <code>ViewSet</code> class and the serializer and queryset will be automatically generated for you. Setting the <code>queryset</code> and/or <code>serializer_class</code> attributes gives you more explicit control of the API behaviour, and is the recommended style for most applications.</p>
|
||||
<h2 id="urls">URLs</h2>
|
||||
<p>Okay, now let's wire up the API URLs. On to <code>tutorial/urls.py</code>...</p>
|
||||
<pre><code>from django.conf.urls import url, include
|
||||
|
|
Loading…
Reference in New Issue
Block a user