Commit 144701c8 by Tom Christie

Update documentation

parent ccf3829d
......@@ -278,6 +278,10 @@
</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>
......
......@@ -278,6 +278,10 @@
</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>
......
......@@ -278,6 +278,10 @@
</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>
......
......@@ -278,6 +278,10 @@
</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>
......
......@@ -278,6 +278,10 @@
</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>
......@@ -382,6 +386,10 @@
</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>
......
......@@ -278,6 +278,10 @@
</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>
......
......@@ -278,6 +278,10 @@
</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>
......
......@@ -278,6 +278,10 @@
</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-->
......
......@@ -278,6 +278,10 @@
</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-->
......
......@@ -278,6 +278,10 @@
</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 = '&lt;{next_url}; rel="next"&gt;, &lt;{previous_url}; rel="prev"&gt;'
link = '&lt;{next_url}&gt;; rel="next", &lt;{previous_url}&gt;; rel="prev"'
elif next_url is not None:
link = '&lt;{next_url}; rel="next"&gt;'
link = '&lt;{next_url}&gt;; rel="next"'
elif previous_url is not None:
link = '&lt;{previous_url}; rel="prev"&gt;'
link = '&lt;{previous_url}&gt;; rel="prev"'
else:
link = ''
......
......@@ -278,6 +278,10 @@
</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>
......
......@@ -278,6 +278,10 @@
</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-->
......
......@@ -278,6 +278,10 @@
</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>&lt;form&gt;</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>&lt;form&gt;</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>
......
......@@ -278,6 +278,10 @@
</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>
......
......@@ -278,6 +278,10 @@
</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>
......
......@@ -278,6 +278,10 @@
</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>
......
......@@ -278,6 +278,10 @@
</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>
......
......@@ -278,6 +278,10 @@
</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>
......
......@@ -278,6 +278,10 @@
</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>
......
......@@ -278,6 +278,10 @@
</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>
......
......@@ -278,6 +278,10 @@
</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>
......
......@@ -278,6 +278,10 @@
</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>
......
......@@ -278,6 +278,10 @@
</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
......
......@@ -278,6 +278,10 @@
</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>
......
......@@ -278,6 +278,10 @@
</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>
......
......@@ -278,6 +278,10 @@
</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
}
......
......@@ -278,6 +278,10 @@
</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>
......
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];
}
}
}
};
$(function() {
var initialise_search = function(){
require.config({"baseUrl":"/mkdocs/js"});
require(["search",]);
}
var initilizeSearch = function() {
require.config({ baseUrl: '/mkdocs/js' });
require(['search']);
};
var search_term = getSearchTerm();
if(search_term){
$('#mkdocs_search_modal').modal();
}
$(function() {
var searchTerm = getSearchTerm(),
$searchModal = $('#mkdocs_search_modal'),
$searchQuery = $searchModal.find('#mkdocs-search-query'),
$searchResults = $searchModal.find('#mkdocs-search-results');
$('pre code').parent().addClass('prettyprint well');
$('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();
});
});
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -278,6 +278,10 @@
</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/">
......@@ -278,6 +278,10 @@
</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>
......
......@@ -278,6 +278,10 @@
</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>
......
......@@ -278,6 +278,10 @@
</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>
......
......@@ -278,6 +278,10 @@
</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>
......
......@@ -278,6 +278,10 @@
</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>
......
......@@ -278,6 +278,10 @@
</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>
......
......@@ -278,6 +278,10 @@
</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>
......
......@@ -278,6 +278,10 @@
</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>
......
......@@ -278,6 +278,10 @@
</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>
......@@ -346,6 +350,10 @@
</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=&lt;method&gt;</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 &amp; 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-->
......
......@@ -278,6 +278,10 @@
</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-->
......
......@@ -278,6 +278,10 @@
</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>
......
......@@ -278,6 +278,10 @@
</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>
......
......@@ -278,6 +278,10 @@
</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
......
......@@ -278,6 +278,10 @@
</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>
......
......@@ -278,6 +278,10 @@
</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>
......
......@@ -278,6 +278,10 @@
</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>
......
......@@ -278,6 +278,10 @@
</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>
......
......@@ -278,6 +278,10 @@
</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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment