Deployed 70e4a43 with MkDocs version: 0.15.3

This commit is contained in:
Tom Christie 2016-07-14 12:05:57 +00:00
parent 848f7597c0
commit f6fd01e9ec
62 changed files with 2154 additions and 227 deletions

View File

@ -112,6 +112,10 @@
<a href="tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../../topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -501,7 +509,7 @@
}
</code></pre>
<p>You can also set the authentication scheme on a per-view or per-viewset basis,
using the <code>APIView</code> class based views.</p>
using the <code>APIView</code> class-based views.</p>
<pre><code>from rest_framework.authentication import SessionAuthentication, BasicAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../../topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -453,7 +461,7 @@ class IgnoreClientContentNegotiation(BaseContentNegotiation):
'DEFAULT_CONTENT_NEGOTIATION_CLASS': 'myapp.negotiation.IgnoreClientContentNegotiation',
}
</code></pre>
<p>You can also set the content negotiation used for an individual view, or viewset, using the <code>APIView</code> class based views.</p>
<p>You can also set the content negotiation used for an individual view, or viewset, using the <code>APIView</code> class-based views.</p>
<pre><code>from myapp.negotiation import IgnoreClientContentNegotiation
from rest_framework.response import Response
from rest_framework.views import APIView

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../../topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../../topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../../topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -536,7 +544,7 @@ class PurchaseList(generics.ListAPIView):
}
</code></pre>
<p>You can also set the filter backends on a per-view, or per-viewset basis,
using the <code>GenericAPIView</code> class based views.</p>
using the <code>GenericAPIView</code> class-based views.</p>
<pre><code>from django.contrib.auth.models import User
from myapp.serializers import UserSerializer
from rest_framework import filters
@ -599,8 +607,8 @@ from rest_framework import filters
from rest_framework import generics
class ProductFilter(filters.FilterSet):
min_price = django_filters.NumberFilter(name="price", lookup_type='gte')
max_price = django_filters.NumberFilter(name="price", lookup_type='lte')
min_price = django_filters.NumberFilter(name="price", lookup_expr='gte')
max_price = django_filters.NumberFilter(name="price", lookup_expr='lte')
class Meta:
model = Product
fields = ['category', 'in_stock', 'min_price', 'max_price']

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../../topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -425,7 +433,7 @@ urlpatterns = format_suffix_patterns(urlpatterns, allowed=['json', 'html'])
def comment_list(request, format=None):
# do stuff...
</code></pre>
<p>Or with class based views:</p>
<p>Or with class-based views:</p>
<pre><code>class CommentList(APIView):
def get(self, request, format=None):
# do stuff...

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../../topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -504,7 +512,7 @@
<p>Djangos generic views... were developed as a shortcut for common usage patterns... They take certain common idioms and patterns found in view development and abstract them so that you can quickly write common views of data without having to repeat yourself.</p>
<p>&mdash; <a href="https://docs.djangoproject.com/en/dev/ref/class-based-views/#base-vs-generic-views">Django Documentation</a></p>
</blockquote>
<p>One of the key benefits of class based views is the way they allow you to compose bits of reusable behavior. REST framework takes advantage of this by providing a number of pre-built views that provide for commonly used patterns.</p>
<p>One of the key benefits of class-based views is the way they allow you to compose bits of reusable behavior. REST framework takes advantage of this by providing a number of pre-built views that provide for commonly used patterns.</p>
<p>The generic views provided by REST framework allow you to quickly build API views that map closely to your database models.</p>
<p>If the generic views don't suit the needs of your API, you can drop down to using the regular <code>APIView</code> class, or reuse the mixins and base classes used by the generic views to compose your own set of reusable generic views.</p>
<h2 id="examples"><a class="toclink" href="#examples">Examples</a></h2>

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../../topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../../topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../../topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -477,7 +485,7 @@ sending more complex data than simple forms</p>
}
</code></pre>
<p>You can also set the parsers used for an individual view, or viewset,
using the <code>APIView</code> class based views.</p>
using the <code>APIView</code> class-based views.</p>
<pre><code>from rest_framework.parsers import JSONParser
from rest_framework.response import Response
from rest_framework.views import APIView

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../../topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -503,7 +511,7 @@ or if you override the <code>get_object</code> method on a generic view, then yo
)
</code></pre>
<p>You can also set the authentication policy on a per-view, or per-viewset basis,
using the <code>APIView</code> class based views.</p>
using the <code>APIView</code> class-based views.</p>
<pre><code>from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../../topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../../topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -535,7 +543,7 @@
}
</code></pre>
<p>You can also set the renderers used for an individual view, or viewset,
using the <code>APIView</code> class based views.</p>
using the <code>APIView</code> class-based views.</p>
<pre><code>from django.contrib.auth.models import User
from rest_framework.renderers import JSONRenderer
from rest_framework.response import Response

View File

@ -61,7 +61,7 @@
<a class="repo-link btn btn-inverse btn-small " rel="prev" href="../responses/">
Next <i class="icon-arrow-right icon-white"></i>
</a>
<a class="repo-link btn btn-inverse btn-small " rel="next" href="../../tutorial/6-viewsets-and-routers/">
<a class="repo-link btn btn-inverse btn-small " rel="next" href="../../tutorial/7-schemas-and-client-libraries/">
<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>
@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../../topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../../topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../../topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../../topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../../topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -393,6 +401,16 @@
</li>
<li class="main">
<a href="#alternate-schema-formats">Alternate schema formats</a>
</li>
<li>
<a href="#example">Example</a>
</li>
<li class="main">
<a href="#api-reference">API Reference</a>
</li>
@ -486,7 +504,7 @@ has to be rendered into the actual bytes that are used in the response.</p>
<p><a href="http://www.coreapi.org/specification/encoding/#core-json-encoding">Core JSON</a> is designed as a canonical format for use with Core API.
REST framework includes a renderer class for handling this media type, which
is available as <code>renderers.CoreJSONRenderer</code>.</p>
<p>Other schema formats such as <a href="https://openapis.org/">Open API</a> (Formerly "Swagger"),
<p>Other schema formats such as <a href="https://openapis.org/">Open API</a> ("Swagger"),
<a href="http://json-schema.org/latest/json-schema-hypermedia.html">JSON HyperSchema</a>, or <a href="https://apiblueprint.org/">API Blueprint</a> can
also be supported by implementing a custom renderer class.</p>
<h2 id="schemas-vs-hypermedia"><a class="toclink" href="#schemas-vs-hypermedia">Schemas vs Hypermedia</a></h2>
@ -531,13 +549,24 @@ Content-Type: application/vnd.coreapi+json
}
</code></pre>
<p>This is a great zero-configuration option for when you want to get up and
running really quickly. If you want a little more flexibility over the
schema output then you'll need to consider using <code>SchemaGenerator</code> instead.</p>
running really quickly.</p>
<p>The only other available option to <code>DefaultRouter</code> is <code>schema_renderers</code>, which
may be used to pass the set of renderer classes that can be used to render
schema output.</p>
<pre><code>from rest_framework.renderers import CoreJSONRenderer
from my_custom_package import APIBlueprintRenderer
router = DefaultRouter(schema_title='Server Monitoring API', schema_renderers=[
CoreJSONRenderer, APIBlueprintRenderer
])
</code></pre>
<p>If you want more flexibility over the schema output then you'll need to consider
using <code>SchemaGenerator</code> instead.</p>
<h2 id="using-schemagenerator"><a class="toclink" href="#using-schemagenerator">Using SchemaGenerator</a></h2>
<p>The most common way to add a schema to your API is to use the <code>SchemaGenerator</code>
class to auto-generate the <code>Document</code> instance, and to return that from a view.</p>
<p>This option gives you the flexibility of setting up the schema endpoint
with whatever behaviour you want. For example, you can apply different
with whatever behavior you want. For example, you can apply different
permission, throttling or authentication policies to the schema endpoint.</p>
<p>Here's an example of using <code>SchemaGenerator</code> together with a view to
return the schema.</p>
@ -601,6 +630,26 @@ of the available formats, such as Core JSON or Open API.</p>
rendered to one of many available formats, depending on the client request.</li>
</ul>
<hr />
<h1 id="alternate-schema-formats"><a class="toclink" href="#alternate-schema-formats">Alternate schema formats</a></h1>
<p>In order to support an alternate schema format, you need to implement a custom renderer
class that handles converting a <code>Document</code> instance into a bytestring representation.</p>
<p>If there is a Core API codec package that supports encoding into the format you
want to use then implementing the renderer class can be done by using the codec.</p>
<h2 id="example"><a class="toclink" href="#example">Example</a></h2>
<p>For example, the <code>openapi_codec</code> package provides support for encoding or decoding
to the Open API ("Swagger") format:</p>
<pre><code>from rest_framework import renderers
from openapi_codec import OpenAPICodec
class SwaggerRenderer(renderers.BaseRenderer):
media_type = 'application/openapi+json;version=2.0'
format = 'swagger'
def render(self, data, media_type=None, renderer_context=None):
codec = OpenAPICodec()
return OpenAPICodec.dump(data)
</code></pre>
<hr />
<h1 id="api-reference"><a class="toclink" href="#api-reference">API Reference</a></h1>
<h2 id="schemagenerator"><a class="toclink" href="#schemagenerator">SchemaGenerator</a></h2>
<p>A class that deals with introspecting your API views, which can be used to

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../../topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -1230,7 +1238,7 @@ class BookSerializer(serializers.Serializer):
<li><code>.to_internal_value()</code> - Override this to support deserialization, for write operations.</li>
<li><code>.create()</code> and <code>.update()</code> - Override either or both of these to support saving instances.</li>
</ul>
<p>Because this class provides the same interface as the <code>Serializer</code> class, you can use it with the existing generic class based views exactly as you would for a regular <code>Serializer</code> or <code>ModelSerializer</code>.</p>
<p>Because this class provides the same interface as the <code>Serializer</code> class, you can use it with the existing generic class-based views exactly as you would for a regular <code>Serializer</code> or <code>ModelSerializer</code>.</p>
<p>The only difference you'll notice when doing so is the <code>BaseSerializer</code> classes will not generate HTML forms in the browsable API. This is because the data they return does not include all the field information that would allow each field to be rendered into a suitable HTML input.</p>
<h5 id="read-only-baseserializer-classes"><a class="toclink" href="#read-only-baseserializer-classes">Read-only <code>BaseSerializer</code> classes</a></h5>
<p>To implement a read-only serializer using the <code>BaseSerializer</code> class, we just need to override the <code>.to_representation()</code> method. Let's take a look at an example using a simple Django model:</p>

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../../topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -456,7 +464,7 @@ print api_settings.DEFAULT_AUTHENTICATION_CLASSES
<hr />
<h1 id="api-reference"><a class="toclink" href="#api-reference">API Reference</a></h1>
<h2 id="api-policy-settings"><a class="toclink" href="#api-policy-settings">API policy settings</a></h2>
<p><em>The following settings control the basic API policies, and are applied to every <code>APIView</code> class based view, or <code>@api_view</code> function based view.</em></p>
<p><em>The following settings control the basic API policies, and are applied to every <code>APIView</code> class-based view, or <code>@api_view</code> function based view.</em></p>
<h4 id="default_renderer_classes"><a class="toclink" href="#default_renderer_classes">DEFAULT_RENDERER_CLASSES</a></h4>
<p>A list or tuple of renderer classes, that determines the default set of renderers that may be used when returning a <code>Response</code> object.</p>
<p>Default:</p>
@ -497,7 +505,7 @@ print api_settings.DEFAULT_AUTHENTICATION_CLASSES
<p>Default: <code>'rest_framework.negotiation.DefaultContentNegotiation'</code></p>
<hr />
<h2 id="generic-view-settings"><a class="toclink" href="#generic-view-settings">Generic view settings</a></h2>
<p><em>The following settings control the behavior of the generic class based views.</em></p>
<p><em>The following settings control the behavior of the generic class-based views.</em></p>
<h4 id="default_pagination_serializer_class"><a class="toclink" href="#default_pagination_serializer_class">DEFAULT_PAGINATION_SERIALIZER_CLASS</a></h4>
<hr />
<p><strong>This setting has been removed.</strong></p>

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../../topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../../topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../../topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -452,7 +460,7 @@ If any throttle check fails an <code>exceptions.Throttled</code> exception will
</code></pre>
<p>The rate descriptions used in <code>DEFAULT_THROTTLE_RATES</code> may include <code>second</code>, <code>minute</code>, <code>hour</code> or <code>day</code> as the throttle period.</p>
<p>You can also set the throttling policy on a per-view or per-viewset basis,
using the <code>APIView</code> class based views.</p>
using the <code>APIView</code> class-based views.</p>
<pre><code>from rest_framework.response import Response
from rest_framework.throttling import UserRateThrottle
from rest_framework.views import APIView

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../../topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -425,7 +433,7 @@
</li>
<li>
<a href="#class-based">Class based</a>
<a href="#class-based">Class-based</a>
</li>
@ -650,8 +658,8 @@ that the resulting behavior is more transparent.</p>
if value % 2 != 0:
raise serializers.ValidationError('This field must be an even number.')
</code></pre>
<h2 id="class-based"><a class="toclink" href="#class-based">Class based</a></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>
<h2 id="class-based"><a class="toclink" href="#class-based">Class-based</a></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(object):
def __init__(self, base):
self.base = base
@ -662,7 +670,7 @@ that the resulting behavior is more transparent.</p>
raise serializers.ValidationError(message)
</code></pre>
<h4 id="using-set_context"><a class="toclink" href="#using-set_context">Using <code>set_context()</code></a></h4>
<p>In some advanced cases you might want a validator to be passed the serializer field it is being used with as additional context. You can do so by declaring a <code>set_context</code> method on a class based validator.</p>
<p>In some advanced cases you might want a validator to be passed the serializer field it is being used with as additional context. You can do so by declaring a <code>set_context</code> method on a class-based validator.</p>
<pre><code>def set_context(self, serializer_field):
# Determine if this is an update or a create operation.
# In `__call__` we can then use that information to modify the validation behavior.

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../../topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../../topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -354,7 +362,7 @@
<li class="main">
<a href="#class-based-views">Class Based Views</a>
<a href="#class-based-views">Class-based Views</a>
</li>
@ -413,9 +421,9 @@
<h1 id="class-based-views"><a class="toclink" href="#class-based-views">Class Based Views</a></h1>
<h1 id="class-based-views"><a class="toclink" href="#class-based-views">Class-based Views</a></h1>
<blockquote>
<p>Django's class based views are a welcome departure from the old-style views.</p>
<p>Django's class-based views are a welcome departure from the old-style views.</p>
<p>&mdash; <a href="http://reinout.vanrees.org/weblog/2011/08/24/class-based-views-usage.html">Reinout van Rees</a></p>
</blockquote>
<p>REST framework provides an <code>APIView</code> class, which subclasses Django's <code>View</code> class.</p>
@ -490,7 +498,7 @@ This method is used to enforce permissions and throttling, and perform content n
<hr />
<h1 id="function-based-views"><a class="toclink" href="#function-based-views">Function Based Views</a></h1>
<blockquote>
<p>Saying [that Class based views] is always the superior solution is a mistake.</p>
<p>Saying [that class-based views] is always the superior solution is a mistake.</p>
<p>&mdash; <a href="http://www.boredomandlaziness.org/2012/05/djangos-cbvs-are-not-mistake-but.html">Nick Coghlan</a></p>
</blockquote>
<p>REST framework also allows you to work with regular function based views. It provides a set of simple decorators that wrap your function based views to ensure they receive an instance of <code>Request</code> (rather than the usual Django <code>HttpRequest</code>) and allows them to return a <code>Response</code> (instead of a Django <code>HttpResponse</code>), and allow you to configure how the request is processed.</p>

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../../topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -112,6 +112,10 @@
<a href="tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -516,7 +524,7 @@ Right now we're over 58% of the way towards achieving that.
<div style="clear: both; padding-bottom: 20px;"></div>
<p><em>Many thanks to all our <a href="https://fund.django-rest-framework.org/topics/funding/#our-sponsors">awesome sponsors</a>, and in particular to our premium backers, <a href="http://jobs.rover.com/">Rover</a>, <a href="https://getsentry.com/welcome/">Sentry</a>, and <a href="https://getstream.io/?utm_source=drf&amp;utm_medium=banner&amp;utm_campaign=drf">Stream</a>.</em></p>
<p><em>Many thanks to all our <a href="https://fund.django-rest-framework.org/topics/funding/#our-sponsors">wonderful sponsors</a>, and in particular to our premium backers, <a href="http://jobs.rover.com/">Rover</a>, <a href="https://getsentry.com/welcome/">Sentry</a>, and <a href="https://getstream.io/?utm_source=drf&amp;utm_medium=banner&amp;utm_campaign=drf">Stream</a>.</em></p>
<hr />
<h2 id="requirements"><a class="toclink" href="#requirements">Requirements</a></h2>
<p>REST framework requires the following:</p>
@ -526,7 +534,7 @@ Right now we're over 58% of the way towards achieving that.
</ul>
<p>The following packages are optional:</p>
<ul>
<li><a href="http://pypi.python.org/pypi/coreapi/">coreapi</a> (1.21.0+) - Schema generation support.</li>
<li><a href="http://pypi.python.org/pypi/coreapi/">coreapi</a> (1.32.0+) - Schema generation support.</li>
<li><a href="http://pypi.python.org/pypi/Markdown/">Markdown</a> (2.1.0+) - Markdown support for the browsable API.</li>
<li><a href="http://pypi.python.org/pypi/django-filter">django-filter</a> (0.9.2+) - Filtering support.</li>
<li><a href="https://github.com/maraujop/django-crispy-forms">django-crispy-forms</a> - Improved HTML display for filtering.</li>
@ -603,10 +611,11 @@ urlpatterns = [
<ul>
<li><a href="tutorial/1-serialization/">1 - Serialization</a></li>
<li><a href="tutorial/2-requests-and-responses/">2 - Requests &amp; Responses</a></li>
<li><a href="tutorial/3-class-based-views/">3 - Class based views</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 &amp; permissions</a></li>
<li><a href="tutorial/5-relationships-and-hyperlinked-apis/">5 - Relationships &amp; hyperlinked APIs</a></li>
<li><a href="tutorial/6-viewsets-and-routers/">6 - Viewsets &amp; routers</a></li>
<li><a href="tutorial/7-schemas-and-client-libraries/">7 - Schemas &amp; client libraries</a></li>
</ul>
<p>There is a live example API of the finished tutorial API for testing purposes, <a href="http://restframework.herokuapp.com/">available here</a>.</p>
<h2 id="api-guide"><a class="toclink" href="#api-guide">API Guide</a></h2>
@ -632,6 +641,7 @@ urlpatterns = [
<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/schemas.md'">Schemas</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>
@ -643,6 +653,7 @@ urlpatterns = [
<p>General guides to using REST framework.</p>
<ul>
<li><a href="topics/documenting-your-api/">Documenting your API</a></li>
<li><a href="topics/api-clients/">API Clients</a></li>
<li><a href="topics/internationalization/">Internationalization</a></li>
<li><a href="topics/ajax-csrf-cors/">AJAX, CSRF &amp; CORS</a></li>
<li><a href="topics/html-and-forms/">HTML &amp; Forms</a></li>
@ -656,6 +667,7 @@ urlpatterns = [
<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/3.3-announcement/">3.3 Announcement</a></li>
<li><a href="topics/3.4-announcement/">3.4 Announcement</a></li>
<li><a href="topics/kickstarter-announcement/">Kickstarter Announcement</a></li>
<li><a href="topics/mozilla-grant/">Mozilla Grant</a></li>
<li><a href="topics/funding/">Funding</a></li>

File diff suppressed because one or more lines are too long

View File

@ -4,7 +4,7 @@
<url>
<loc>http://www.django-rest-framework.org//</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
@ -13,43 +13,49 @@
<url>
<loc>http://www.django-rest-framework.org//tutorial/quickstart/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//tutorial/1-serialization/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//tutorial/2-requests-and-responses/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//tutorial/3-class-based-views/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//tutorial/4-authentication-and-permissions/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//tutorial/5-relationships-and-hyperlinked-apis/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//tutorial/6-viewsets-and-routers/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//tutorial/7-schemas-and-client-libraries/</loc>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
@ -59,163 +65,163 @@
<url>
<loc>http://www.django-rest-framework.org//api-guide/requests/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//api-guide/responses/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//api-guide/views/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//api-guide/generic-views/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//api-guide/viewsets/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//api-guide/routers/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//api-guide/parsers/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//api-guide/renderers/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//api-guide/serializers/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//api-guide/fields/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//api-guide/relations/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//api-guide/validators/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//api-guide/authentication/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//api-guide/permissions/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//api-guide/throttling/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//api-guide/filtering/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//api-guide/pagination/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//api-guide/versioning/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//api-guide/content-negotiation/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//api-guide/metadata/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//api-guide/schemas/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//api-guide/format-suffixes/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//api-guide/reverse/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//api-guide/exceptions/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//api-guide/status-codes/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//api-guide/testing/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//api-guide/settings/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
@ -225,115 +231,121 @@
<url>
<loc>http://www.django-rest-framework.org//topics/documenting-your-api/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//topics/api-clients/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//topics/internationalization/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//topics/ajax-csrf-cors/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//topics/html-and-forms/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//topics/browser-enhancements/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//topics/browsable-api/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//topics/rest-hypermedia-hateoas/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//topics/third-party-resources/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//topics/contributing/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//topics/project-management/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//topics/3.0-announcement/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//topics/3.1-announcement/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//topics/3.2-announcement/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//topics/3.3-announcement/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//topics/3.4-announcement/</loc>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//topics/kickstarter-announcement/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//topics/mozilla-grant/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//topics/funding/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>http://www.django-rest-framework.org//topics/release-notes/</loc>
<lastmod>2016-07-07</lastmod>
<lastmod>2016-07-14</lastmod>
<changefreq>daily</changefreq>
</url>

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -746,7 +754,7 @@ InvitationSerializer():
<li><code>.to_internal_value()</code> - Override this to support deserialization, for write operations.</li>
<li><code>.create()</code> and <code>.update()</code> - Override either or both of these to support saving instances.</li>
</ul>
<p>Because this class provides the same interface as the <code>Serializer</code> class, you can use it with the existing generic class based views exactly as you would for a regular <code>Serializer</code> or <code>ModelSerializer</code>.</p>
<p>Because this class provides the same interface as the <code>Serializer</code> class, you can use it with the existing generic class-based views exactly as you would for a regular <code>Serializer</code> or <code>ModelSerializer</code>.</p>
<p>The only difference you'll notice when doing so is the <code>BaseSerializer</code> classes will not generate HTML forms in the browsable API. This is because the data they return does not include all the field information that would allow each field to be rendered into a suitable HTML input.</p>
<h5 id="read-only-baseserializer-classes"><a class="toclink" href="#read-only-baseserializer-classes">Read-only <code>BaseSerializer</code> classes.</a></h5>
<p>To implement a read-only serializer using the <code>BaseSerializer</code> class, we just need to override the <code>.to_representation()</code> method. Let's take a look at an example using a simple Django model:</p>
@ -1038,7 +1046,7 @@ class OrganizationSerializer(serializers.Serializer):
<p>This change means that you can now easily customize the style of error responses across your entire API, without having to modify any of the generic views.</p>
<hr />
<h2 id="the-metadata-api"><a class="toclink" href="#the-metadata-api">The metadata API</a></h2>
<p>Behavior for dealing with <code>OPTIONS</code> requests was previously built directly into the class based views. This has now been properly separated out into a Metadata API that allows the same pluggable style as other API policies in REST framework.</p>
<p>Behavior for dealing with <code>OPTIONS</code> requests was previously built directly into the class-based views. This has now been properly separated out into a Metadata API that allows the same pluggable style as other API policies in REST framework.</p>
<p>This makes it far easier to use a different style for <code>OPTIONS</code> responses throughout your API, and makes it possible to create third-party metadata policies.</p>
<hr />
<h2 id="serializers-as-html-forms"><a class="toclink" href="#serializers-as-html-forms">Serializers as HTML forms</a></h2>

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -58,7 +58,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.4-announcement/">
Next <i class="icon-arrow-right icon-white"></i>
</a>
<a class="repo-link btn btn-inverse btn-small " rel="next" href="../3.2-announcement/">
@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="./">3.3 Announcement</a>
</li>
<li >
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -0,0 +1,607 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<title>3.4 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.4-announcement/" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Django, API, REST, 3.4 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>
#sidebarInclude img {
margin-bottom: 10px;
}
#sidebarInclude a.promo {
color: black;
}
@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.3-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>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</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/schemas/">Schemas</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="../api-clients/">API Clients</a>
</li>
<li >
<a href="../internationalization/">Internationalization</a>
</li>
<li >
<a href="../ajax-csrf-cors/">AJAX, CSRF & CORS</a>
</li>
<li >
<a href="../html-and-forms/">HTML & Forms</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 >
<a href="../3.2-announcement/">3.2 Announcement</a>
</li>
<li >
<a href="../3.3-announcement/">3.3 Announcement</a>
</li>
<li class="active" >
<a href="./">3.4 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>
<li >
<a href="../mozilla-grant/">Mozilla Grant</a>
</li>
<li >
<a href="../funding/">Funding</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">&times;</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-34">Django REST framework 3.4</a>
</li>
<li>
<a href="#funding">Funding</a>
</li>
<li>
<a href="#schemas-client-libraries">Schemas &amp; client libraries</a>
</li>
<li>
<a href="#supported-versions">Supported versions</a>
</li>
<li>
<a href="#deprecations-and-changes">Deprecations and changes</a>
</li>
<li>
<a href="#other-improvements">Other improvements</a>
</li>
<div class="promo">
<hr/>
<div id="sidebarInclude">
</div>
</ul>
</div>
</div>
<div id="main-content" class="span9">
<style>
.promo li a {
float: left;
width: 130px;
height: 20px;
text-align: center;
margin: 10px 30px;
padding: 150px 0 0 0;
background-position: 0 50%;
background-size: 130px auto;
background-repeat: no-repeat;
font-size: 120%;
color: black;
}
.promo li {
list-style: none;
}
</style>
<h1 id="django-rest-framework-34"><a class="toclink" href="#django-rest-framework-34">Django REST framework 3.4</a></h1>
<p>The 3.4 release is the first in a planned series that will be addressing schema
generation, hypermedia support, API clients, and finally realtime support.</p>
<hr />
<h2 id="funding"><a class="toclink" href="#funding">Funding</a></h2>
<p>The 3.4 release has been made possible a recent <a href="../mozilla-grant/">Mozilla grant</a>, and by our
<a href="../funding/">collaborative funding model</a>. If you use REST framework commercially, and would
like to see this work continue, we strongly encourage you to invest in its
continued development by <strong><a href="../funding/">signing up for a paid plan</a></strong>.</p>
<p>The initial aim is to provide a single full-time position on REST framework.
Right now we're over 60% of the way towards achieving that.
<em>Every single sign-up makes a significant impact.</em></p>
<ul class="premium-promo promo">
<li><a href="http://jobs.rover.com/" style="background-image: url(https://fund-rest-framework.s3.amazonaws.com/rover_130x130.png)">Rover.com</a></li>
<li><a href="https://getsentry.com/welcome/" style="background-image: url(https://fund-rest-framework.s3.amazonaws.com/sentry130.png)">Sentry</a></li>
<li><a href="https://getstream.io/?utm_source=drf&utm_medium=banner&utm_campaign=drf" style="background-image: url(https://fund-rest-framework.s3.amazonaws.com/stream-130.png)">Stream</a></li>
</ul>
<div style="clear: both; padding-bottom: 20px;"></div>
<p><em>Many thanks to all our <a href="https://fund.django-rest-framework.org/topics/funding/#our-sponsors">awesome sponsors</a>, and in particular to our premium backers, <a href="http://jobs.rover.com/">Rover</a>, <a href="https://getsentry.com/welcome/">Sentry</a>, and <a href="https://getstream.io/?utm_source=drf&amp;utm_medium=banner&amp;utm_campaign=drf">Stream</a>.</em></p>
<hr />
<h2 id="schemas-client-libraries"><a class="toclink" href="#schemas-client-libraries">Schemas &amp; client libraries</a></h2>
<p>REST framework 3.4 brings built-in support for generating API schemas.</p>
<p>We provide this support by using <a href="http://www.coreapi.org/">Core API</a>, a Document Object Model
for describing APIs.</p>
<p>Because Core API represents the API schema in an format-independent
manner, we're able to render the Core API <code>Document</code> object into many different
schema formats, by allowing the renderer class to determine how the internal
representation maps onto the external schema format.</p>
<p>This approach should also open the door to a range of auto-generated API
documentation options in the future, by rendering the <code>Document</code> object into
HTML documentation pages.</p>
<p>Alongside the built-in schema support, we're also now providing the following:</p>
<ul>
<li>A <a href="../api-clients#command-line-client">command line tool</a> for interacting with APIs.</li>
<li>A <a href="../api-clients#python-client-library">Python client library</a> for interacting with APIs.</li>
</ul>
<p>These API clients are dynamically driven, and able to interact with any API
that exposes a supported schema format.</p>
<p>Dynamically driven clients allow you to interact with an API at an application
layer interface, rather than a network layer interface, while still providing
the benefits of RESTful Web API design.</p>
<p>We're expecting to expand the range of languages that we provide client libraries
for over the coming months.</p>
<p>Further work on maturing the API schema support is also planned, including
documentation on supporting file upload and download, and improved support for
documentation generation and parameter annotation.</p>
<hr />
<p>Current support for schema formats is as follows:</p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Support</th>
<th>PyPI package</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="http://www.coreapi.org/specification/encoding/#core-json-encoding">Core JSON</a></td>
<td>Schema generation &amp; client support.</td>
<td>Built-in support in <code>coreapi</code></td>
</tr>
<tr>
<td><a href="https://openapis.org/specification">Swagger / OpenAPI</a></td>
<td>Schema generation &amp; client support.</td>
<td>The <code>openapi-codec</code>package.</td>
</tr>
<tr>
<td><a href="http://json-schema.org/latest/json-schema-hypermedia.html">JSON Hyper-Schema</a></td>
<td>Currrently client support only.</td>
<td>The <code>hyperschema-codec</code>package.</td>
</tr>
<tr>
<td><a href="https://apiblueprint.org/">API Blueprint</a></td>
<td>Not yet available.</td>
<td>Not yet available.</td>
</tr>
</tbody>
</table>
<hr />
<p>You can read more about any of this new functionality in the following:</p>
<ul>
<li>New tutorial section on <a href="../../../tutorial/7-schemas-and-client-libraries/">schemas &amp; client libraries</a>.</li>
<li>Documentation page on <a href="../../../api-guide/schemas/">schema generation</a>.</li>
<li>Topic page on <a href="../api-clients/">API clients</a>.</li>
</ul>
<p>It is also worth noting that Marc Gibbons is currently working towards a 2.0 release of
the popular Django REST Swagger package, which will tie in with our new built-in support.</p>
<hr />
<h2 id="supported-versions"><a class="toclink" href="#supported-versions">Supported versions</a></h2>
<p>The 3.4.0 release adds support for Django 1.10.</p>
<p>The following versions of Python and Django are now supported:</p>
<ul>
<li>Django versions 1.8, 1.9, and 1.10.</li>
<li>Python versions 2.7, 3.2(*), 3.3(*), 3.4, 3.5.</li>
</ul>
<p>(*) Note that Python 3.2 and 3.3 are not supported from Django 1.9 onwards.</p>
<hr />
<h2 id="deprecations-and-changes"><a class="toclink" href="#deprecations-and-changes">Deprecations and changes</a></h2>
<p>The 3.4 release includes very limited deprecation or behavioral changes, and
should present a straightforward upgrade.</p>
<h3 id="use-fields-or-exclude-on-serializer-classes"><a class="toclink" href="#use-fields-or-exclude-on-serializer-classes">Use fields or exclude on serializer classes.</a></h3>
<p>The following change in 3.3.0 is now escalated from "pending deprecation" to
"deprecated". Its usage will continue to function but will raise warnings:</p>
<p><code>ModelSerializer</code> and <code>HyperlinkedModelSerializer</code> should include either a <code>fields</code>
option, or an <code>exclude</code> option. The <code>fields = '__all__'</code> shortcut may be used
to explicitly include all fields.</p>
<h3 id="microsecond-precision-when-returning-time-or-datetime"><a class="toclink" href="#microsecond-precision-when-returning-time-or-datetime">Microsecond precision when returning time or datetime.</a></h3>
<p>Using the default JSON renderer and directly returning a <code>datetime</code> or <code>time</code>
instance will now render with microsecond precision (6 digits), rather than
millisecond precision (3 digits). This makes the output format consistent with the
default string output of <code>serializers.DateTimeField</code> and <code>serializers.TimeField</code>.</p>
<p>This change <em>does not affect the default behavior when using serializers</em>,
which is to serialize <code>datetime</code> and <code>time</code> instances into strings with
microsecond precision.</p>
<p>The serializer behavior can be modified if needed, using the <code>DATETIME_FORMAT</code>
and <code>TIME_FORMAT</code> settings.</p>
<p>The renderer behavior can be modified by setting a custom <code>encoder_class</code>
attribute on a <code>JSONRenderer</code> subclass.</p>
<h3 id="relational-choices-no-longer-displayed-in-options-requests"><a class="toclink" href="#relational-choices-no-longer-displayed-in-options-requests">Relational choices no longer displayed in OPTIONS requests.</a></h3>
<p>Making an <code>OPTIONS</code> request to views that have a serializer choice field
will result in a list of the available choices being returned in the response.</p>
<p>In cases where there is a relational field, the previous behavior would be
to return a list of available instances to choose from for that relational field.</p>
<p>In order to minimise exposed information the behavior now is to <em>not</em> return
choices information for relational fields.</p>
<p>If you want to override this new behavior you'll need to <a href="../../../api-guide/metadata/#custom-metadata-classes">implement a custom
metadata class</a>.</p>
<p>See <a href="https://github.com/tomchristie/django-rest-framework/issues/3751">issue #3751</a> for more information on this behavioral change.</p>
<hr />
<h2 id="other-improvements"><a class="toclink" href="#other-improvements">Other improvements</a></h2>
<p>This release includes further work from a huge number of <a href="https://github.com/tomchristie/django-rest-framework/milestone/35">pull requests and issues</a>.</p>
<p>Many thanks to all our contributors who've been involved in the release, either through raising issues, giving feedback, improving the documentation, or suggesting and implementing code changes.</p>
<p>The full set of itemized release notes <a href="../release-notes#34">are available here</a>.</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>.
</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 src="https://fund.django-rest-framework.org/sidebar_include.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>

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -376,6 +384,10 @@
<a href="#authentication-headers">Authentication &amp; headers</a>
</li>
<li>
<a href="#codecs">Codecs</a>
</li>
<li>
<a href="#utilities">Utilities</a>
</li>
@ -395,7 +407,7 @@
</li>
<li>
<a href="#codecs">Codecs</a>
<a href="#codecs_1">Codecs</a>
</li>
<li>
@ -456,7 +468,9 @@ up to date with the most recently deployed version of the service.</p>
exposes a supported schema format.</p>
<h2 id="getting-started"><a class="toclink" href="#getting-started">Getting started</a></h2>
<p>To install the Core API command line client, use <code>pip</code>.</p>
<pre><code>$ pip install coreapi
<p>Note that the command-line client is a separate package to the
python client library. Make sure to install <code>coreapi-cli</code>.</p>
<pre><code>$ pip install coreapi-cli
</code></pre>
<p>To start inspecting and interacting with an API the schema must first be loaded
from the network.</p>
@ -512,54 +526,75 @@ of keys that are used to index into the link.</p>
]
</code></pre>
<p>Some actions may include optional or required parameters.</p>
<pre><code>$ coreapi action users create --params username example
<pre><code>$ coreapi action users create --param username=example
</code></pre>
<p>When using <code>--param</code>, the type of the input will be determined automatically.</p>
<p>If you want to be more explicit about the parameter type then use <code>--data</code> for
any null, numeric, boolean, list, or object inputs, and use <code>--string</code> for string inputs.</p>
<pre><code>$ coreapi action users edit --string username=tomchristie --data is_admin=true
</code></pre>
<h2 id="authentication-headers"><a class="toclink" href="#authentication-headers">Authentication &amp; headers</a></h2>
<p>The <code>credentials</code> command is used to manage the request <code>Authentication:</code> header.
Any credentials added are always linked to a particular domain, so as to ensure
that credentials are not leaked across differing APIs.</p>
<p>The format for adding a new credential is:</p>
<pre><code>coreapi credentials add &lt;domain&gt; &lt;credentials string&gt;
<pre><code>$ coreapi credentials add &lt;domain&gt; &lt;credentials string&gt;
</code></pre>
<p>For instance:</p>
<pre><code>coreapi credentials add api.example.org "Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b"
<pre><code>$ coreapi credentials add api.example.org "Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b"
</code></pre>
<p>The optional <code>--auth</code> flag also allows you to add specific types of authentication,
handling the encoding for you. Currently only <code>"basic"</code> is supported as an option here.
For example:</p>
<pre><code>coreapi credentials add api.example.org tomchristie:foobar --auth basic
<pre><code>$ coreapi credentials add api.example.org tomchristie:foobar --auth basic
</code></pre>
<p>You can also add specific request headers, using the <code>headers</code> command:</p>
<pre><code>coreapi headers add api.example.org x-api-version 2
<pre><code>$ coreapi headers add api.example.org x-api-version 2
</code></pre>
<p>For more information and a listing of the available subcommands use <code>coreapi
credentials --help</code> or <code>coreapi headers --help</code>.</p>
<h2 id="codecs"><a class="toclink" href="#codecs">Codecs</a></h2>
<p>By default the command line client only includes support for reading Core JSON
schemas, however it includes a plugin system for installing additional codecs.</p>
<pre><code>$ pip install openapi-codec jsonhyperschema-codec hal-codec
$ coreapi codecs show
Codecs
corejson application/vnd.coreapi+json encoding, decoding
hal application/hal+json encoding, decoding
openapi application/openapi+json encoding, decoding
jsonhyperschema application/schema+json decoding
json application/json data
text text/* data
</code></pre>
<h2 id="utilities"><a class="toclink" href="#utilities">Utilities</a></h2>
<p>The command line client includes functionality for bookmarking API URLs
under a memorable name. For example, you can add a bookmark for the
existing API, like so...</p>
<pre><code>coreapi bookmarks add accountmanagement
<pre><code>$ coreapi bookmarks add accountmanagement
</code></pre>
<p>There is also functionality for navigating forward or backward through the
history of which API URLs have been accessed.</p>
<pre><code>coreapi history show
coreapi history back
<pre><code>$ coreapi history show
$ coreapi history back
</code></pre>
<p>For more information and a listing of the available subcommands use
<code>coreapi bookmarks --help</code> or <code>coreapi history --help</code>.</p>
<h2 id="other-commands"><a class="toclink" href="#other-commands">Other commands</a></h2>
<p>To display the current <code>Document</code>:</p>
<pre><code>coreapi show
<pre><code>$ coreapi show
</code></pre>
<p>To reload the current <code>Document</code> from the network:</p>
<pre><code>coreapi reload
<pre><code>$ coreapi reload
</code></pre>
<p>To load a schema file from disk:</p>
<pre><code>coreapi load my-api-schema.json --format corejson
<pre><code>$ coreapi load my-api-schema.json --format corejson
</code></pre>
<p>To dump the current document to console in a given format:</p>
<pre><code>$ coreapi dump --format openapi
</code></pre>
<p>To remove the current document, along with all currently saved history,
credentials, headers and bookmarks:</p>
<pre><code>coreapi clear
<pre><code>$ coreapi clear
</code></pre>
<hr />
<h1 id="python-client-library"><a class="toclink" href="#python-client-library">Python client library</a></h1>
@ -567,7 +602,9 @@ credentials, headers and bookmarks:</p>
API that exposes a supported schema format.</p>
<h2 id="getting-started_1"><a class="toclink" href="#getting-started_1">Getting started</a></h2>
<p>You'll need to install the <code>coreapi</code> package using <code>pip</code> before you can get
started. Once you've done so, open up a python terminal.</p>
started.</p>
<pre><code>$ pip install coreapi
</code></pre>
<p>In order to start working with an API, we first need a <code>Client</code> instance. The
client holds any configuration around which codecs and transports are supported
when interacting with an API, which allows you to provide for more advanced
@ -586,7 +623,7 @@ the internal representation of the interface that we are interacting with.</p>
<p>Some endpoints may include named parameters, which might be either optional or required:</p>
<pre><code>new_user = client.action(schema, ['users', 'create'], params={"username": "max"})
</code></pre>
<h2 id="codecs"><a class="toclink" href="#codecs">Codecs</a></h2>
<h2 id="codecs_1"><a class="toclink" href="#codecs_1">Codecs</a></h2>
<p>Codecs are responsible for encoding or decoding Documents.</p>
<p>The decoding process is used by a client to take a bytestring of an API schema
definition, and returning the Core API <code>Document</code> that represents that interface.</p>
@ -608,13 +645,14 @@ client = Client(decoders=decoders)
<h4 id="loading-and-saving-schemas"><a class="toclink" href="#loading-and-saving-schemas">Loading and saving schemas</a></h4>
<p>You can use a codec directly, in order to load an existing schema definition,
and return the resulting <code>Document</code>.</p>
<pre><code>schema_definition = open('my-api-schema.json', 'r').read()
<pre><code>input_file = open('my-api-schema.json', 'rb')
schema_definition = input_file.read()
codec = codecs.CoreJSONCodec()
schema = codec.load(schema_definition)
</code></pre>
<p>You can also use a codec directly to generate a schema definition given a <code>Document</code> instance:</p>
<pre><code>schema_definition = codec.dump(schema)
output_file = open('my-api-schema.json', 'r')
output_file = open('my-api-schema.json', 'rb')
output_file.write(schema_definition)
</code></pre>
<h2 id="transports"><a class="toclink" href="#transports">Transports</a></h2>

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -61,7 +61,7 @@
<a class="repo-link btn btn-inverse btn-small " rel="prev" href="../mozilla-grant/">
Next <i class="icon-arrow-right icon-white"></i>
</a>
<a class="repo-link btn btn-inverse btn-small " rel="next" href="../3.3-announcement/">
<a class="repo-link btn btn-inverse btn-small " rel="next" href="../3.4-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>
@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li class="active" >
<a href="./">Kickstarter Announcement</a>
</li>

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -438,12 +446,94 @@
</code></pre>
<hr />
<h2 id="34x-series"><a class="toclink" href="#34x-series">3.4.x series</a></h2>
<h3 id="34"><a class="toclink" href="#34">3.4</a></h3>
<p><strong>Unreleased</strong></p>
<h3 id="340"><a class="toclink" href="#340">3.4.0</a></h3>
<p><strong>Date</strong>: <a href="https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.4.0+Release%22">14th July 2016</a></p>
<ul>
<li>Dropped support for EOL Django 1.7 ([#3933][gh3933])</li>
<li>Fixed null foreign keys targeting UUIDField primary keys. ([#3936][gh3936])</li>
<li>Don't strip microseconds in JSON output. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4256">#4256</a>)</li>
<li>Two slightly different iso 8601 datetime serialization. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4255">#4255</a>)</li>
<li>Resolve incorrect inclusion of media type parameters. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4254">#4254</a>)</li>
<li>Response Content-Type potentially malformed. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4253">#4253</a>)</li>
<li>Fix setup.py error on some platforms. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4246">#4246</a>)</li>
<li>Move alternate formats in coreapi into separate packages. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4244">#4244</a>)</li>
<li>Add localize keyword argument to <code>DecimalField</code>. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4233">#4233</a>)</li>
<li>Fix issues with routers for custom list-route and detail-routes. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4229">#4229</a>)</li>
<li>Namespace versioning with nested namespaces. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4219">#4219</a>)</li>
<li>Robust uniqueness checks. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4217">#4217</a>)</li>
<li>Minor refactoring of <code>must_call_distinct</code>. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4215">#4215</a>)</li>
<li>Overridable offset cutoff in CursorPagination. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4212">#4212</a>)</li>
<li>Pass through strings as-in with date/time fields. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4196">#4196</a>)</li>
<li>Add test confirming that required=False is valid on a relational field. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4195">#4195</a>)</li>
<li>In LimitOffsetPagination <code>limit=0</code> should revert to default limit. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4194">#4194</a>)</li>
<li>Exclude read_only=True fields from unique_together validation &amp; add docs. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4192">#4192</a>)</li>
<li>Handle bytestrings in JSON. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4191">#4191</a>)</li>
<li>JSONField(binary=True) represents using binary strings, which JSONRenderer does not support. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4187">#4187</a>)</li>
<li>JSONField(binary=True) represents using binary strings, which JSONRenderer does not support. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4185">#4185</a>)</li>
<li>More robust form rendering in the browsable API. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4181">#4181</a>)</li>
<li>Empty cases of <code>.validated_data</code> and <code>.errors</code> as lists not dicts for ListSerializer. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4180">#4180</a>)</li>
<li>Schemas &amp; client libraries. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4179">#4179</a>)</li>
<li>Removed <code>AUTH_USER_MODEL</code> compat property. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4176">#4176</a>)</li>
<li>Clean up existing deprecation warnings. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4166">#4166</a>)</li>
<li>Django 1.10 support. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4158">#4158</a>)</li>
<li>Updated jQuery version to 1.12.4. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4157">#4157</a>)</li>
<li>More robust default behavior on OrderingFilter. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4156">#4156</a>)</li>
<li>description.py codes and tests removal. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4153">#4153</a>)</li>
<li>Wrap guardian.VERSION in tuple. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4149">#4149</a>)</li>
<li>Refine validator for fields with <source=> kwargs. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4146">#4146</a>)</li>
<li>Fix None values representation in childs of ListField, DictField. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4118">#4118</a>)</li>
<li>Resolve TimeField representation for midnight value. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4107">#4107</a>)</li>
<li>Set proper status code in AdminRenderer for the redirection after POST/DELETE requests. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4106">#4106</a>)</li>
<li>TimeField render returns None instead of 00:00:00. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4105">#4105</a>)</li>
<li>Fix incorrectly named zh-hans and zh-hant locale path. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4103">#4103</a>)</li>
<li>Prevent raising exception when limit is 0. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4098">#4098</a>)</li>
<li>TokenAuthentication: Allow custom keyword in the header. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4097">#4097</a>)</li>
<li>Handle incorrectly padded HTTP basic auth header. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4090">#4090</a>)</li>
<li>LimitOffset pagination crashes Browseable API when limit=0. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4079">#4079</a>)</li>
<li>Fixed DecimalField arbitrary precision support. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4075">#4075</a>)</li>
<li>Added support for custom CSRF cookie names. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4049">#4049</a>)</li>
<li>Fix regression introduced by #4035. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4041">#4041</a>)</li>
<li>No auth view failing permission should raise 403. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4040">#4040</a>)</li>
<li>Fix string_types / text_types confusion. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4025">#4025</a>)</li>
<li>Do not list related field choices in OPTIONS requests. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4021">#4021</a>)</li>
<li>Fix typo. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4008">#4008</a>)</li>
<li>Reorder initializing the view. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4006">#4006</a>)</li>
<li>Type error in DjangoObjectPermissionsFilter on Python 3.4. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4005">#4005</a>)</li>
<li>Fixed use of deprecated Query.aggregates. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4003">#4003</a>)</li>
<li>Fix blank lines around docstrings. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4002">#4002</a>)</li>
<li>Fixed admin pagination when limit is 0. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3990">#3990</a>)</li>
<li>OrderingFilter adjustements. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3983">#3983</a>)</li>
<li>Non-required serializer related fields. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3976">#3976</a>)</li>
<li>Using safer calling way of "@api_view" in tutorial. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3971">#3971</a>)</li>
<li>ListSerializer doesn't handle unique_together constraints. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3970">#3970</a>)</li>
<li>Add missing migration file. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3968">#3968</a>)</li>
<li><code>OrderingFilter</code> should call <code>get_serializer_class()</code> to determine default fields. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3964">#3964</a>)</li>
<li>Remove old django checks from tests and compat. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3953">#3953</a>)</li>
<li>Support callable as the value of <code>initial</code> for any <code>serializer.Field</code>. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3943">#3943</a>)</li>
<li>Prevented unnecessary distinct() call in SearchFilter. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3938">#3938</a>)</li>
<li>Fix None UUID ForeignKey serialization. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3936">#3936</a>)</li>
<li>Drop EOL Django 1.7. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3933">#3933</a>)</li>
<li>Add missing space in serializer error message. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3926">#3926</a>)</li>
<li>Fixed _force_text_recursive typo. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3908">#3908</a>)</li>
<li>Attempt to address Django 2.0 deprecate warnings related to <code>field.rel</code>. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3906">#3906</a>)</li>
<li>Fix parsing multipart data using a nested serializer with list. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3820">#3820</a>)</li>
<li>Resolving APIs URL to different namespaces. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3816">#3816</a>)</li>
<li>Do not HTML-escape <code>help_text</code> in Browsable API forms. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3812">#3812</a>)</li>
<li>OPTIONS fetches and shows all possible foreign keys in choices field. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3751">#3751</a>)</li>
<li>Django 1.9 deprecation warnings (<a href="https://github.com/tomchristie/django-rest-framework/issues/3729">#3729</a>)</li>
<li>Test case for #3598 (<a href="https://github.com/tomchristie/django-rest-framework/issues/3710">#3710</a>)</li>
<li>Adding support for multiple values for search filter. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3541">#3541</a>)</li>
<li>Use get_serializer_class in ordering filter. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3487">#3487</a>)</li>
<li>Serializers with many=True should return empty list rather than empty dict. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3476">#3476</a>)</li>
<li>LimitOffsetPagination limit=0 fix. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3444">#3444</a>)</li>
<li>Enable Validators to defer string evaluation and handle new string format. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3438">#3438</a>)</li>
<li>Unique validator is executed and breaks if field is invalid. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3381">#3381</a>)</li>
<li>Do not ignore overridden View.get_view_name() in breadcrumbs. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3273">#3273</a>)</li>
<li>Retry form rendering when rendering with serializer fails. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3164">#3164</a>)</li>
<li>Unique constraint prevents nested serializers from updating. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2996">#2996</a>)</li>
<li>Uniqueness validators should not be run for excluded (read_only) fields. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2848">#2848</a>)</li>
<li>UniqueValidator raises exception for nested objects. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2403">#2403</a>)</li>
<li><code>lookup_type</code> is deprecated in favor of <code>lookup_expr</code>. (<a href="https://github.com/tomchristie/django-rest-framework/issues/4259">#4259</a>)</li>
</ul>
<hr />
<h2 id="33x-series"><a class="toclink" href="#33x-series">3.3.x series</a></h2>
<h3 id="333"><a class="toclink" href="#333">3.3.3</a></h3>
<p><strong>Date</strong>: <a href="https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.3.3+Release%22">14th March 2016</a>.</p>
@ -519,6 +609,7 @@
<li>Removed support for Django 1.5 &amp; 1.6. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3421">#3421</a>, <a href="https://github.com/tomchristie/django-rest-framework/issues/3429">#3429</a>)</li>
<li>Removed 'south' migrations. (<a href="https://github.com/tomchristie/django-rest-framework/issues/3495">#3495</a>)</li>
</ul>
<hr />
<h2 id="32x-series"><a class="toclink" href="#32x-series">3.2.x series</a></h2>
<h3 id="325"><a class="toclink" href="#325">3.2.5</a></h3>
<p><strong>Date</strong>: <a href="https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.2.5+Release%22">27th October 2015</a>.</p>
@ -769,6 +860,8 @@
<!-- 3.3.2 -->
<!-- 3.3.3 -->
<!-- 3.4.0 -->
</div> <!--/span-->

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -112,6 +112,10 @@
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../../tutorial/7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -112,6 +112,10 @@
<a href="../6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../../topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -112,6 +112,10 @@
<a href="../6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../../topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -423,7 +431,7 @@ request.data # Handles arbitrary data. Works for 'POST', 'PUT' and 'PATCH' met
<p>REST framework provides two wrappers you can use to write API views.</p>
<ol>
<li>The <code>@api_view</code> decorator for working with function based views.</li>
<li>The <code>APIView</code> class for working with class based views.</li>
<li>The <code>APIView</code> class for working with class-based views.</li>
</ol>
<p>These wrappers provide a few bits of functionality such as making sure you receive <code>Request</code> instances in your view, and adding context to <code>Response</code> objects so that content negotiation can be performed.</p>
<p>The wrappers also provide behaviour such as returning <code>405 Method Not Allowed</code> responses when appropriate, and handling any <code>ParseError</code> exception that occurs when accessing <code>request.data</code> with malformed input.</p>
@ -484,7 +492,7 @@ def snippet_detail(request, pk):
<p>This should all feel very familiar - it is not a lot different from working with regular Django views.</p>
<p>Notice that we're no longer explicitly tying our requests or responses to a given content type. <code>request.data</code> can handle incoming <code>json</code> requests, but it can also handle other formats. Similarly we're returning response objects with data, but allowing REST framework to render the response into the correct content type for us.</p>
<h2 id="adding-optional-format-suffixes-to-our-urls"><a class="toclink" href="#adding-optional-format-suffixes-to-our-urls">Adding optional format suffixes to our URLs</a></h2>
<p>To take advantage of the fact that our responses are no longer hardwired to a single content type let's add support for format suffixes to our API endpoints. Using format suffixes gives us URLs that explicitly refer to a given format, and means our API will be able to handle URLs such as <a href="http://example.com/api/items/4/.json">http://example.com/api/items/4/.json</a>.</p>
<p>To take advantage of the fact that our responses are no longer hardwired to a single content type let's add support for format suffixes to our API endpoints. Using format suffixes gives us URLs that explicitly refer to a given format, and means our API will be able to handle URLs such as <a href="http://example.com/api/items/4.json">http://example.com/api/items/4.json</a>.</p>
<p>Start by adding a <code>format</code> keyword argument to both of the views, like so.</p>
<pre><code>def snippet_list(request, format=None):
</code></pre>
@ -570,7 +578,7 @@ http --json POST http://127.0.0.1:8000/snippets/ code="print 456"
<p>Having a web-browsable API is a huge usability win, and makes developing and using your API much easier. It also dramatically lowers the barrier-to-entry for other developers wanting to inspect and work with your API.</p>
<p>See the <a href="../../topics/browsable-api/">browsable api</a> topic for more information about the browsable API feature and how to customize it.</p>
<h2 id="whats-next"><a class="toclink" href="#whats-next">What's next?</a></h2>
<p>In <a href="../3-class-based-views/">tutorial part 3</a>, we'll start using class based views, and see how generic views reduce the amount of code we need to write.</p>
<p>In <a href="../3-class-based-views/">tutorial part 3</a>, we'll start using class-based views, and see how generic views reduce the amount of code we need to write.</p>
</div> <!--/span-->

View File

@ -112,6 +112,10 @@
<a href="../6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../../topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -354,12 +362,12 @@
<li class="main">
<a href="#tutorial-3-class-based-views">Tutorial 3: Class Based Views</a>
<a href="#tutorial-3-class-based-views">Tutorial 3: Class-based Views</a>
</li>
<li>
<a href="#rewriting-our-api-using-class-based-views">Rewriting our API using class based views</a>
<a href="#rewriting-our-api-using-class-based-views">Rewriting our API using class-based views</a>
</li>
<li>
@ -367,7 +375,7 @@
</li>
<li>
<a href="#using-generic-class-based-views">Using generic class based views</a>
<a href="#using-generic-class-based-views">Using generic class-based views</a>
</li>
@ -385,10 +393,10 @@
<h1 id="tutorial-3-class-based-views"><a class="toclink" href="#tutorial-3-class-based-views">Tutorial 3: Class Based Views</a></h1>
<p>We can also write our API views using class based views, rather than function based views. As we'll see this is a powerful pattern that allows us to reuse common functionality, and helps us keep our code <a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">DRY</a>.</p>
<h2 id="rewriting-our-api-using-class-based-views"><a class="toclink" href="#rewriting-our-api-using-class-based-views">Rewriting our API using class based views</a></h2>
<p>We'll start by rewriting the root view as a class based view. All this involves is a little bit of refactoring of <code>views.py</code>.</p>
<h1 id="tutorial-3-class-based-views"><a class="toclink" href="#tutorial-3-class-based-views">Tutorial 3: Class-based Views</a></h1>
<p>We can also write our API views using class-based views, rather than function based views. As we'll see this is a powerful pattern that allows us to reuse common functionality, and helps us keep our code <a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">DRY</a>.</p>
<h2 id="rewriting-our-api-using-class-based-views"><a class="toclink" href="#rewriting-our-api-using-class-based-views">Rewriting our API using class-based views</a></h2>
<p>We'll start by rewriting the root view as a class-based view. All this involves is a little bit of refactoring of <code>views.py</code>.</p>
<pre><code>from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
from django.http import Http404
@ -443,7 +451,7 @@ class SnippetList(APIView):
return Response(status=status.HTTP_204_NO_CONTENT)
</code></pre>
<p>That's looking good. Again, it's still pretty similar to the function based view right now.</p>
<p>We'll also need to refactor our <code>urls.py</code> slightly now we're using class based views.</p>
<p>We'll also need to refactor our <code>urls.py</code> slightly now we're using class-based views.</p>
<pre><code>from django.conf.urls import url
from rest_framework.urlpatterns import format_suffix_patterns
from snippets import views
@ -457,7 +465,7 @@ urlpatterns = format_suffix_patterns(urlpatterns)
</code></pre>
<p>Okay, we're done. If you run the development server everything should be working just as before.</p>
<h2 id="using-mixins"><a class="toclink" href="#using-mixins">Using mixins</a></h2>
<p>One of the big wins of using class based views is that it allows us to easily compose reusable bits of behaviour.</p>
<p>One of the big wins of using class-based views is that it allows us to easily compose reusable bits of behaviour.</p>
<p>The create/retrieve/update/delete operations that we've been using so far are going to be pretty similar for any model-backed API views we create. Those bits of common behaviour are implemented in REST framework's mixin classes.</p>
<p>Let's take a look at how we can compose the views by using the mixin classes. Here's our <code>views.py</code> module again.</p>
<pre><code>from snippets.models import Snippet
@ -496,7 +504,7 @@ class SnippetList(mixins.ListModelMixin,
return self.destroy(request, *args, **kwargs)
</code></pre>
<p>Pretty similar. Again we're using the <code>GenericAPIView</code> class to provide the core functionality, and adding in mixins to provide the <code>.retrieve()</code>, <code>.update()</code> and <code>.destroy()</code> actions.</p>
<h2 id="using-generic-class-based-views"><a class="toclink" href="#using-generic-class-based-views">Using generic class based views</a></h2>
<h2 id="using-generic-class-based-views"><a class="toclink" href="#using-generic-class-based-views">Using generic class-based views</a></h2>
<p>Using the mixin classes we've rewritten the views to use slightly less code than before, but we can go one step further. REST framework provides a set of already mixed-in generic views that we can use to trim down our <code>views.py</code> module even more.</p>
<pre><code>from snippets.models import Snippet
from snippets.serializers import SnippetSerializer

View File

@ -112,6 +112,10 @@
<a href="../6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../../topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -466,7 +474,7 @@ class UserSerializer(serializers.ModelSerializer):
fields = ('id', 'username', 'snippets')
</code></pre>
<p>Because <code>'snippets'</code> is a <em>reverse</em> relationship on the User model, it will not be included by default when using the <code>ModelSerializer</code> class, so we needed to add an explicit field for it.</p>
<p>We'll also add a couple of views to <code>views.py</code>. We'd like to just use read-only views for the user representations, so we'll use the <code>ListAPIView</code> and <code>RetrieveAPIView</code> generic class based views.</p>
<p>We'll also add a couple of views to <code>views.py</code>. We'd like to just use read-only views for the user representations, so we'll use the <code>ListAPIView</code> and <code>RetrieveAPIView</code> generic class-based views.</p>
<pre><code>from django.contrib.auth.models import User

View File

@ -112,6 +112,10 @@
<a href="../6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../../topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -413,7 +421,7 @@ def api_root(request, format=None):
'snippets': reverse('snippet-list', request=request, format=format)
})
</code></pre>
<p>Two things should be noticed here. First, we're using REST framework's <code>reverse</code> function in order to return fully-qualified URLs; second, URL patterns are identified by convenience names that we will declare later on in our <code>snippets/urls.py</code>. </p>
<p>Two things should be noticed here. First, we're using REST framework's <code>reverse</code> function in order to return fully-qualified URLs; second, URL patterns are identified by convenience names that we will declare later on in our <code>snippets/urls.py</code>.</p>
<h2 id="creating-an-endpoint-for-the-highlighted-snippets"><a class="toclink" href="#creating-an-endpoint-for-the-highlighted-snippets">Creating an endpoint for the highlighted snippets</a></h2>
<p>The other obvious thing that's still missing from our pastebin API is the code highlighting endpoints.</p>
<p>Unlike all our other API endpoints, we don't want to use JSON, but instead just present an HTML representation. There are two styles of HTML renderer provided by REST framework, one for dealing with HTML rendered using templates, the other for dealing with pre-rendered HTML. The second renderer is the one we'd like to use for this endpoint.</p>
@ -463,7 +471,7 @@ We'll add a url pattern for our new API root in <code>snippets/urls.py</code>:</
class Meta:
model = Snippet
fields = ('url', 'highlight', 'owner',
fields = ('url', 'pk', 'highlight', 'owner',
'title', 'code', 'linenos', 'language', 'style')
@ -472,7 +480,7 @@ class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ('url', 'username', 'snippets')
fields = ('url', 'pk', 'username', 'snippets')
</code></pre>
<p>Notice that we've also added a new <code>'highlight'</code> field. This field is of the same type as the <code>url</code> field, except that it points to the <code>'snippet-highlight'</code> url pattern, instead of the <code>'snippet-detail'</code> url pattern.</p>
<p>Because we've included format suffixed URLs such as <code>'.json'</code>, we also need to indicate on the <code>highlight</code> field that any format suffixed hyperlinks it returns should use the <code>'.html'</code> suffix.</p>

View File

@ -58,7 +58,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="../../api-guide/requests/">
<a class="repo-link btn btn-inverse btn-small " rel="prev" href="../7-schemas-and-client-libraries/">
Next <i class="icon-arrow-right icon-white"></i>
</a>
<a class="repo-link btn btn-inverse btn-small " rel="next" href="../5-relationships-and-hyperlinked-apis/">
@ -112,6 +112,10 @@
<a href="./">6 - Viewsets and routers</a>
</li>
<li >
<a href="../7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../../topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -374,14 +382,6 @@
<a href="#trade-offs-between-views-vs-viewsets">Trade-offs between views vs viewsets</a>
</li>
<li>
<a href="#reviewing-our-work">Reviewing our work</a>
</li>
<li>
<a href="#onwards-and-upwards">Onwards and upwards</a>
</li>
<div class="promo">
@ -503,17 +503,8 @@ urlpatterns = [
<h2 id="trade-offs-between-views-vs-viewsets"><a class="toclink" href="#trade-offs-between-views-vs-viewsets">Trade-offs between views vs viewsets</a></h2>
<p>Using viewsets can be a really useful abstraction. It helps ensure that URL conventions will be consistent across your API, minimizes the amount of code you need to write, and allows you to concentrate on the interactions and representations your API provides rather than the specifics of the URL conf.</p>
<p>That doesn't mean it's always the right approach to take. There's a similar set of trade-offs to consider as when using class-based views instead of function based views. Using viewsets is less explicit than building your views individually.</p>
<h2 id="reviewing-our-work"><a class="toclink" href="#reviewing-our-work">Reviewing our work</a></h2>
<p>With an incredibly small amount of code, we've now got a complete pastebin Web API, which is fully web browsable, includes a schema-driven client library, and comes complete with authentication, per-object permissions, and multiple renderer formats.</p>
<p>We've walked through each step of the design process, and seen how if we need to customize anything we can gradually work our way down to simply using regular Django views.</p>
<p>You can review the final <a href="https://github.com/tomchristie/rest-framework-tutorial">tutorial code</a> on GitHub, or try out a live example in <a href="http://restframework.herokuapp.com/">the sandbox</a>.</p>
<h2 id="onwards-and-upwards"><a class="toclink" href="#onwards-and-upwards">Onwards and upwards</a></h2>
<p>We've reached the end of our tutorial. If you want to get more involved in the REST framework project, here are a few places you can start:</p>
<ul>
<li>Contribute on <a href="https://github.com/tomchristie/django-rest-framework">GitHub</a> by reviewing and submitting issues, and making pull requests.</li>
<li>Join the <a href="https://groups.google.com/forum/?fromgroups#!forum/django-rest-framework">REST framework discussion group</a>, and help build the community.</li>
<li>Follow <a href="https://twitter.com/_tomchristie">the author</a> on Twitter and say hi.</li>
</ul>
<p>In <a href="../7-schemas-and-client-libraries/">part 7</a> of the tutorial we'll look at how we can add an API schema,
and interact with our API using a client library or command line tool.</p>
</div> <!--/span-->

View File

@ -0,0 +1,630 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<title>7 - Schemas and client libraries - 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/tutorial/7-schemas-and-client-libraries/" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Django, API, REST, 7 - Schemas and client libraries">
<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>
#sidebarInclude img {
margin-bottom: 10px;
}
#sidebarInclude a.promo {
color: black;
}
@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="../../api-guide/requests/">
Next <i class="icon-arrow-right icon-white"></i>
</a>
<a class="repo-link btn btn-inverse btn-small " rel="next" href="../6-viewsets-and-routers/">
<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 active">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Tutorial <b class="caret"></b></a>
<ul class="dropdown-menu">
<li >
<a href="../quickstart/">Quickstart</a>
</li>
<li >
<a href="../1-serialization/">1 - Serialization</a>
</li>
<li >
<a href="../2-requests-and-responses/">2 - Requests and responses</a>
</li>
<li >
<a href="../3-class-based-views/">3 - Class based views</a>
</li>
<li >
<a href="../4-authentication-and-permissions/">4 - Authentication and permissions</a>
</li>
<li >
<a href="../5-relationships-and-hyperlinked-apis/">5 - Relationships and hyperlinked APIs</a>
</li>
<li >
<a href="../6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li class="active" >
<a href="./">7 - Schemas and client libraries</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/schemas/">Schemas</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">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Topics <b class="caret"></b></a>
<ul class="dropdown-menu">
<li >
<a href="../../topics/documenting-your-api/">Documenting your API</a>
</li>
<li >
<a href="../../topics/api-clients/">API Clients</a>
</li>
<li >
<a href="../../topics/internationalization/">Internationalization</a>
</li>
<li >
<a href="../../topics/ajax-csrf-cors/">AJAX, CSRF & CORS</a>
</li>
<li >
<a href="../../topics/html-and-forms/">HTML & Forms</a>
</li>
<li >
<a href="../../topics/browser-enhancements/">Browser Enhancements</a>
</li>
<li >
<a href="../../topics/browsable-api/">The Browsable API</a>
</li>
<li >
<a href="../../topics/rest-hypermedia-hateoas/">REST, Hypermedia & HATEOAS</a>
</li>
<li >
<a href="../../topics/third-party-resources/">Third Party Resources</a>
</li>
<li >
<a href="../../topics/contributing/">Contributing to REST framework</a>
</li>
<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/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>
<li >
<a href="../../topics/mozilla-grant/">Mozilla Grant</a>
</li>
<li >
<a href="../../topics/funding/">Funding</a>
</li>
<li >
<a href="../../topics/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">&times;</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="#tutorial-7-schemas-client-libraries">Tutorial 7: Schemas &amp; client libraries</a>
</li>
<li>
<a href="#core-api">Core API</a>
</li>
<li>
<a href="#adding-a-schema">Adding a schema</a>
</li>
<li>
<a href="#using-a-command-line-client">Using a command line client</a>
</li>
<li>
<a href="#authenticating-our-client">Authenticating our client</a>
</li>
<li>
<a href="#reviewing-our-work">Reviewing our work</a>
</li>
<li>
<a href="#onwards-and-upwards">Onwards and upwards</a>
</li>
<div class="promo">
<hr/>
<div id="sidebarInclude">
</div>
</ul>
</div>
</div>
<div id="main-content" class="span9">
<h1 id="tutorial-7-schemas-client-libraries"><a class="toclink" href="#tutorial-7-schemas-client-libraries">Tutorial 7: Schemas &amp; client libraries</a></h1>
<p>A schema is a machine-readable document that describes the available API
endpoints, their URLS, and what operations they support.</p>
<p>Schemas can be a useful tool for auto-generated documentation, and can also
be used to drive dynamic client libraries that can interact with the API.</p>
<h2 id="core-api"><a class="toclink" href="#core-api">Core API</a></h2>
<p>In order to provide schema support REST framework uses <a href="http://www.coreapi.org">Core API</a>.</p>
<p>Core API is a document specification for describing APIs. It is used to provide
an internal representation format of the available endpoints and possible
interactions that an API exposes. It can either be used server-side, or
client-side.</p>
<p>When used server-side, Core API allows an API to support rendering to a wide
range of schema or hypermedia formats.</p>
<p>When used client-side, Core API allows for dynamically driven client libraries
that can interact with any API that exposes a supported schema or hypermedia
format.</p>
<h2 id="adding-a-schema"><a class="toclink" href="#adding-a-schema">Adding a schema</a></h2>
<p>REST framework supports either explicitly defined schema views, or
automatically generated schemas. Since we're using viewsets and routers,
we can simply use the automatic schema generation.</p>
<p>You'll need to install the <code>coreapi</code> python package in order to include an
API schema.</p>
<pre><code>$ pip install coreapi
</code></pre>
<p>We can now include a schema for our API, by adding a <code>schema_title</code> argument to
the router instantiation.</p>
<pre><code>router = DefaultRouter(schema_title='Pastebin API')
</code></pre>
<p>If you visit the API root endpoint in a browser you should now see <code>corejson</code>
representation become available as an option.</p>
<p><img alt="Schema format" src="../../img/corejson-format.png" /></p>
<p>We can also request the schema from the command line, by specifying the desired
content type in the <code>Accept</code> header.</p>
<pre><code>$ http http://127.0.0.1:8000/ Accept:application/vnd.coreapi+json
HTTP/1.0 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/vnd.coreapi+json
{
"_meta": {
"title": "Pastebin API"
},
"_type": "document",
...
</code></pre>
<p>The default output style is to use the <a href="http://www.coreapi.org/specification/encoding/#core-json-encoding">Core JSON</a> encoding.</p>
<p>Other schema formats, such as <a href="https://openapis.org/">Open API</a> (formerly Swagger) are
also supported.</p>
<h2 id="using-a-command-line-client"><a class="toclink" href="#using-a-command-line-client">Using a command line client</a></h2>
<p>Now that our API is exposing a schema endpoint, we can use a dynamic client
library to interact with the API. To demonstrate this, let's use the
Core API command line client.</p>
<p>The command line client is available as the <code>coreapi-cli</code> package:</p>
<pre><code>$ pip install coreapi-cli
</code></pre>
<p>Now check that it is available on the command line...</p>
<pre><code>$ coreapi
Usage: coreapi [OPTIONS] COMMAND [ARGS]...
Command line client for interacting with CoreAPI services.
Visit http://www.coreapi.org for more information.
Options:
--version Display the package version number.
--help Show this message and exit.
Commands:
...
</code></pre>
<p>First we'll load the API schema using the command line client.</p>
<pre><code>$ coreapi get http://127.0.0.1:8000/
&lt;Pastebin API "http://127.0.0.1:8000/"&gt;
snippets: {
highlight(pk)
list()
retrieve(pk)
}
users: {
list()
retrieve(pk)
}
</code></pre>
<p>We haven't authenticated yet, so right now we're only able to see the read only
endpoints, in line with how we've set up the permissions on the API.</p>
<p>Let's try listing the existing snippets, using the command line client:</p>
<pre><code>$ coreapi action snippets list
[
{
"url": "http://127.0.0.1:8000/snippets/1/",
"pk": 1,
"highlight": "http://127.0.0.1:8000/snippets/1/highlight/",
"owner": "lucy",
"title": "Example",
"code": "print('hello, world!')",
"linenos": true,
"language": "python",
"style": "friendly"
},
...
</code></pre>
<p>Some of the API endpoints require named parameters. For example, to get back
the highlight HTML for a particular snippet we need to provide an id.</p>
<pre><code>$ coreapi action snippets highlight --param pk 1
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"&gt;
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Example&lt;/title&gt;
...
</code></pre>
<h2 id="authenticating-our-client"><a class="toclink" href="#authenticating-our-client">Authenticating our client</a></h2>
<p>If we want to be able to create, edit and delete snippets, we'll need to
authenticate as a valid user. In this case we'll just use basic auth.</p>
<p>Make sure to replace the <code>&lt;username&gt;</code> and <code>&lt;password&gt;</code> below with your
actual username and password.</p>
<pre><code>$ coreapi credentials add 127.0.0.1 &lt;username&gt;:&lt;password&gt; --auth basic
Added credentials
127.0.0.1 "Basic &lt;...&gt;"
</code></pre>
<p>Now if we fetch the schema again, we should be able to see the full
set of available interactions.</p>
<pre><code>$ coreapi reload
Pastebin API "http://127.0.0.1:8000/"&gt;
snippets: {
create(code, [title], [linenos], [language], [style])
destroy(pk)
highlight(pk)
list()
partial_update(pk, [title], [code], [linenos], [language], [style])
retrieve(pk)
update(pk, code, [title], [linenos], [language], [style])
}
users: {
list()
retrieve(pk)
}
</code></pre>
<p>We're now able to interact with these endpoints. For example, to create a new
snippet:</p>
<pre><code>$ coreapi action snippets create --param title "Example" --param code "print('hello, world')"
{
"url": "http://127.0.0.1:8000/snippets/7/",
"pk": 7,
"highlight": "http://127.0.0.1:8000/snippets/7/highlight/",
"owner": "lucy",
"title": "Example",
"code": "print('hello, world')",
"linenos": false,
"language": "python",
"style": "friendly"
}
</code></pre>
<p>And to delete a snippet:</p>
<pre><code>$ coreapi action snippets destroy --param pk 7
</code></pre>
<p>As well as the command line client, developers can also interact with your
API using client libraries. The Python client library is the first of these
to be available, and a Javascript client library is planned to be released
soon.</p>
<p>For more details on customizing schema generation and using Core API
client libraries you'll need to refer to the full documentation.</p>
<h2 id="reviewing-our-work"><a class="toclink" href="#reviewing-our-work">Reviewing our work</a></h2>
<p>With an incredibly small amount of code, we've now got a complete pastebin Web API, which is fully web browsable, includes a schema-driven client library, and comes complete with authentication, per-object permissions, and multiple renderer formats.</p>
<p>We've walked through each step of the design process, and seen how if we need to customize anything we can gradually work our way down to simply using regular Django views.</p>
<p>You can review the final <a href="https://github.com/tomchristie/rest-framework-tutorial">tutorial code</a> on GitHub, or try out a live example in <a href="http://restframework.herokuapp.com/">the sandbox</a>.</p>
<h2 id="onwards-and-upwards"><a class="toclink" href="#onwards-and-upwards">Onwards and upwards</a></h2>
<p>We've reached the end of our tutorial. If you want to get more involved in the REST framework project, here are a few places you can start:</p>
<ul>
<li>Contribute on <a href="https://github.com/tomchristie/django-rest-framework">GitHub</a> by reviewing and submitting issues, and making pull requests.</li>
<li>Join the <a href="https://groups.google.com/forum/?fromgroups#!forum/django-rest-framework">REST framework discussion group</a>, and help build the community.</li>
<li>Follow <a href="https://twitter.com/_tomchristie">the author</a> on Twitter and say hi.</li>
</ul>
<p><strong>Now go build awesome things.</strong></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>.
</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 src="https://fund.django-rest-framework.org/sidebar_include.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>

View File

@ -112,6 +112,10 @@
<a href="../6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
<li >
<a href="../7-schemas-and-client-libraries/">7 - Schemas and client libraries</a>
</li>
</ul>
</li>
@ -294,6 +298,10 @@
<a href="../../topics/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -486,7 +494,7 @@ urlpatterns = [
]
</code></pre>
<p>Because we're using viewsets instead of views, we can automatically generate the URL conf for our API, by simply registering the viewsets with a router class.</p>
<p>Again, if we need more control over the API URLs we can simply drop down to using regular class based views, and writing the URL conf explicitly.</p>
<p>Again, if we need more control over the API URLs we can simply drop down to using regular class-based views, and writing the URL conf explicitly.</p>
<p>Finally, we're including default login and logout views for use with the browsable API. That's optional, but useful if your API requires authentication and you want to use the browsable API.</p>
<h2 id="settings"><a class="toclink" href="#settings">Settings</a></h2>
<p>We'd also like to set a few global settings. We'd like to turn on pagination, and we want our API to only be accessible to admin users. The settings module will be in <code>tutorial/settings.py</code></p>