Deployed c6f1686 with MkDocs version: 0.15.3

This commit is contained in:
Tom Christie 2016-10-20 15:31:37 +00:00
parent fdb68f719a
commit 8175ad0c2e
61 changed files with 1243 additions and 170 deletions

View File

@ -302,6 +302,10 @@
<a href="topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -786,7 +790,7 @@ color_channel = serializers.ChoiceField(
<p>Format strings may either be <a href="http://docs.python.org/2/library/datetime.html#strftime-and-strptime-behavior">Python strftime formats</a> which explicitly specify the format, or the special string <code>'iso-8601'</code>, which indicates that <a href="http://www.w3.org/TR/NOTE-datetime">ISO 8601</a> style datetimes should be used. (eg <code>'2013-01-29T12:34:56.000000Z'</code>)</p>
<p>When a value of <code>None</code> is used for the format <code>datetime</code> objects will be returned by <code>to_representation</code> and the final output representation will determined by the renderer class.</p>
<p>In the case of JSON this means the default datetime representation uses the <a href="http://ecma-international.org/ecma-262/5.1/#sec-15.9.1.15">ECMA 262 date time string specification</a>. This is a subset of ISO 8601 which uses millisecond precision, and includes the 'Z' suffix for the UTC timezone, for example: <code>2013-01-29T12:34:56.123Z</code>.</p>
<h4 id="auto_now-and-auto_now_add-model-fields"><a class="toclink" href="#auto_now-and-auto_now_add-model-fields"><code>auto_now</code> and <code>auto_now_add</code> model fields.</a></h4>
<h4 id="auto_now-and-auto_now_add-model-fields"><code>auto_now_add</code> model fields.<a class="toclink" href="#auto_now-and-auto_now_add-model-fields"><code>auto_now</code> and </a></h4>
<p>When using <code>ModelSerializer</code> or <code>HyperlinkedModelSerializer</code>, note that any model fields with <code>auto_now=True</code> or <code>auto_now_add=True</code> will use serializer fields that are <code>read_only=True</code> by default.</p>
<p>If you want to override this behavior, you'll need to declare the <code>DateTimeField</code> explicitly on the serializer. For example:</p>
<pre><code>class CommentSerializer(serializers.ModelSerializer):

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -548,20 +552,20 @@ class PurchaseList(generics.ListAPIView):
<h2 id="setting-filter-backends"><a class="toclink" href="#setting-filter-backends">Setting filter backends</a></h2>
<p>The default filter backends may be set globally, using the <code>DEFAULT_FILTER_BACKENDS</code> setting. For example.</p>
<pre><code>REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': ('rest_framework.filters.DjangoFilterBackend',)
'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
}
</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>
<pre><code>from django.contrib.auth.models import User
<pre><code>import django_filters
from django.contrib.auth.models import User
from myapp.serializers import UserSerializer
from rest_framework import filters
from rest_framework import generics
class UserListView(generics.ListAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
filter_backends = (filters.DjangoFilterBackend,)
filter_backends = (django_filters.rest_framework.DjangoFilterBackend,)
</code></pre>
<h2 id="filtering-and-object-lookups"><a class="toclink" href="#filtering-and-object-lookups">Filtering and object lookups</a></h2>
<p>Note that if a filter backend is configured for a view, then as well as being used to filter list views, it will also be used to filter the querysets used for returning a single object.</p>
@ -586,10 +590,23 @@ class UserListView(generics.ListAPIView):
<hr />
<h1 id="api-guide"><a class="toclink" href="#api-guide">API Guide</a></h1>
<h2 id="djangofilterbackend"><a class="toclink" href="#djangofilterbackend">DjangoFilterBackend</a></h2>
<p>The <code>DjangoFilterBackend</code> class supports highly customizable field filtering, using the <a href="https://github.com/alex/django-filter">django-filter package</a>.</p>
<p>To use REST framework's <code>DjangoFilterBackend</code>, first install <code>django-filter</code>.</p>
<p>The <code>django-filter</code> library includes a <code>DjangoFilterBackend</code> class which
supports highly customizable field filtering for REST framework.</p>
<p>To use <code>DjangoFilterBackend</code>, first install <code>django-filter</code>.</p>
<pre><code>pip install django-filter
</code></pre>
<p>You should now either add the filter backend to your settings:</p>
<pre><code>REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
}
</code></pre>
<p>Or add the filter backend to an individual View or ViewSet.</p>
<pre><code>from django_filters.rest_framework import DjangoFilterBackend
class UserListView(generics.ListAPIView):
...
filter_backends = (DjangoFilterBackend,)
</code></pre>
<p>If you are using the browsable API or admin API you may also want to install <code>django-crispy-forms</code>, which will enhance the presentation of the filter forms in HTML views, by allowing them to render Bootstrap 3 HTML.</p>
<pre><code>pip install django-crispy-forms
</code></pre>
@ -611,10 +628,9 @@ class UserListView(generics.ListAPIView):
<pre><code>import django_filters
from myapp.models import Product
from myapp.serializers import ProductSerializer
from rest_framework import filters
from rest_framework import generics
class ProductFilter(filters.FilterSet):
class ProductFilter(django_filters.rest_framework.FilterSet):
min_price = django_filters.NumberFilter(name="price", lookup_expr='gte')
max_price = django_filters.NumberFilter(name="price", lookup_expr='lte')
class Meta:
@ -624,7 +640,7 @@ class ProductFilter(filters.FilterSet):
class ProductList(generics.ListAPIView):
queryset = Product.objects.all()
serializer_class = ProductSerializer
filter_backends = (filters.DjangoFilterBackend,)
filter_backends = (django_filters.rest_framework.DjangoFilterBackend,)
filter_class = ProductFilter
</code></pre>
<p>Which will allow you to make requests such as:</p>
@ -633,12 +649,12 @@ class ProductList(generics.ListAPIView):
<p>You can also span relationships using <code>django-filter</code>, let's assume that each
product has foreign key to <code>Manufacturer</code> model, so we create filter that
filters using <code>Manufacturer</code> name. For example:</p>
<pre><code>from myapp.models import Product
<pre><code>import django_filters
from myapp.models import Product
from myapp.serializers import ProductSerializer
from rest_framework import filters
from rest_framework import generics
class ProductFilter(filters.FilterSet):
class ProductFilter(django_filters.rest_framework.FilterSet):
class Meta:
model = Product
fields = ['category', 'in_stock', 'manufacturer__name']
@ -650,10 +666,9 @@ class ProductFilter(filters.FilterSet):
<pre><code>import django_filters
from myapp.models import Product
from myapp.serializers import ProductSerializer
from rest_framework import filters
from rest_framework import generics
class ProductFilter(filters.FilterSet):
class ProductFilter(django_filters.rest_framework.FilterSet):
manufacturer = django_filters.CharFilter(name="manufacturer__name")
class Meta:

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -738,12 +742,12 @@ generate a schema.</p>
</code></pre>
<p>Arguments:</p>
<ul>
<li><code>title</code> - The name of the API. <strong>required</strong></li>
<li><code>title</code> <strong>required</strong> - The name of the API.</li>
<li><code>url</code> - The root URL of the API schema. This option is not required unless the schema is included under path prefix.</li>
<li><code>patterns</code> - A list of URLs to inspect when generating the schema. Defaults to the project's URL conf.</li>
<li><code>urlconf</code> - A URL conf module name to use when generating the schema. Defaults to <code>settings.ROOT_URLCONF</code>.</li>
</ul>
<h3 id="get_schema"><a class="toclink" href="#get_schema">get_schema()</a></h3>
<h3 id="get_schemaself-request"><a class="toclink" href="#get_schemaself-request">get_schema(self, request)</a></h3>
<p>Returns a <code>coreapi.Document</code> instance that represents the API schema.</p>
<pre><code>@api_view
@renderer_classes([renderers.CoreJSONRenderer])
@ -751,10 +755,30 @@ def schema_view(request):
generator = schemas.SchemaGenerator(title='Bookings API')
return Response(generator.get_schema())
</code></pre>
<p>Arguments:</p>
<ul>
<li><code>request</code> - The incoming request. Optionally used if you want to apply per-user permissions to the schema-generation.</li>
</ul>
<p>The <code>request</code> argument is optional, and may be used if you want to apply per-user
permissions to the resulting schema generation.</p>
<h3 id="get_linksself-request"><a class="toclink" href="#get_linksself-request">get_links(self, request)</a></h3>
<p>Return a nested dictionary containing all the links that should be included in the API schema.</p>
<p>This is a good point to override if you want to modify the resulting structure of the generated schema,
as you can build a new dictionary with a different layout.</p>
<h3 id="get_linkself-path-method-view"><a class="toclink" href="#get_linkself-path-method-view">get_link(self, path, method, view)</a></h3>
<p>Returns a <code>coreapi.Link</code> instance corresponding to the given view.</p>
<p>You can override this if you need to provide custom behaviors for particular views.</p>
<h3 id="get_descriptionself-path-method-view"><a class="toclink" href="#get_descriptionself-path-method-view">get_description(self, path, method, view)</a></h3>
<p>Returns a string to use as the link description. By default this is based on the
view docstring as described in the "Schemas as Documentation" section above.</p>
<h3 id="get_encodingself-path-method-view"><a class="toclink" href="#get_encodingself-path-method-view">get_encoding(self, path, method, view)</a></h3>
<p>Returns a string to indicate the encoding for any request body, when interacting
with the given view. Eg. <code>'application/json'</code>. May return a blank string for views
that do not expect a request body.</p>
<h3 id="get_path_fieldsself-path-method-view"><a class="toclink" href="#get_path_fieldsself-path-method-view">get_path_fields(self, path, method, view):</a></h3>
<p>Return a list of <code>coreapi.Link()</code> instances. One for each path parameter in the URL.</p>
<h3 id="get_serializer_fieldsself-path-method-view"><a class="toclink" href="#get_serializer_fieldsself-path-method-view">get_serializer_fields(self, path, method, view)</a></h3>
<p>Return a list of <code>coreapi.Link()</code> instances. One for each field in the serializer class used by the view.</p>
<h3 id="get_pagination_fieldsself-path-method-view"><a class="toclink" href="#get_pagination_fieldsself-path-method-view">get_pagination_fields(self, path, method, view</a></h3>
<p>Return a list of <code>coreapi.Link()</code> instances, as returned by the <code>get_schema_fields()</code> method on any pagination class used by the view.</p>
<h3 id="get_filter_fieldsself-path-method-view"><a class="toclink" href="#get_filter_fieldsself-path-method-view">get_filter_fields(self, path, method, view)</a></h3>
<p>Return a list of <code>coreapi.Link()</code> instances, as returned by the <code>get_schema_fields()</code> method of any filter classes used by the view.</p>
<hr />
<h2 id="core-api"><a class="toclink" href="#core-api">Core API</a></h2>
<p>This documentation gives a brief overview of the components within the <code>coreapi</code>

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -628,6 +632,7 @@ using the popular Python library, <code>requests</code>.</p>
directly.</p>
<pre><code>client = RequestsClient()
response = client.get('http://testserver/users/')
assert response.status_code == 200
</code></pre>
<p>Note that the requests client requires you to pass fully qualified URLs.</p>
<h2 id="headers-authentication"><a class="toclink" href="#headers-authentication">Headers &amp; Authentication</a></h2>
@ -672,9 +677,8 @@ do not directly affect customer data.</p>
<p>The CoreAPIClient allows you to interact with your API using the Python
<code>coreapi</code> client library.</p>
<pre><code># Fetch the API schema
url = reverse('schema')
client = CoreAPIClient()
schema = client.get(url)
schema = client.get('http://testserver/schema/')
# Create a new organisation
params = {'name': 'MegaCorp', 'status': 'active'}

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

BIN
img/raml.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

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

View File

@ -302,6 +302,10 @@
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -450,7 +454,7 @@
<hr />
<p><em>Below is an in-depth guide to the API changes and migration notes for 3.0.</em></p>
<h2 id="request-objects"><a class="toclink" href="#request-objects">Request objects</a></h2>
<h4 id="the-data-and-query_params-properties"><a class="toclink" href="#the-data-and-query_params-properties">The <code>.data</code> and <code>.query_params</code> properties.</a></h4>
<h4 id="the-data-and-query_params-properties"><code>.query_params</code> properties.<a class="toclink" href="#the-data-and-query_params-properties">The <code>.data</code> and </a></h4>
<p>The usage of <code>request.DATA</code> and <code>request.FILES</code> is now pending deprecation in favor of a single <code>request.data</code> attribute that contains <em>all</em> the parsed data.</p>
<p>Having separate attributes is reasonable for web applications that only ever parse url-encoded or multipart requests, but makes less sense for the general-purpose request parsing that REST framework supports.</p>
<p>You may now pass all the request data to a serializer class in a single argument:</p>
@ -482,7 +486,7 @@ ExampleSerializer(data=request.DATA, files=request.FILES)
<li>Calling <code>serializer.save()</code> then saves and returns the new object instance.</li>
</ol>
<p>The resulting API changes are further detailed below.</p>
<h4 id="the-create-and-update-methods"><a class="toclink" href="#the-create-and-update-methods">The <code>.create()</code> and <code>.update()</code> methods.</a></h4>
<h4 id="the-create-and-update-methods"><code>.update()</code> methods.<a class="toclink" href="#the-create-and-update-methods">The <code>.create()</code> and </a></h4>
<p>The <code>.restore_object()</code> method is now removed, and we instead have two separate methods, <code>.create()</code> and <code>.update()</code>. These methods work slightly different to the previous <code>.restore_object()</code>.</p>
<p>When using the <code>.create()</code> and <code>.update()</code> methods you should both create <em>and save</em> the object instance. This is in contrast to the previous <code>.restore_object()</code> behavior that would instantiate the object but not save it.</p>
<p>These methods also replace the optional <code>.save_object()</code> method, which no longer exists.</p>
@ -514,7 +518,7 @@ def create(self, validated_data):
return Snippet.objects.create(**validated_data)
</code></pre>
<p>Note that these methods should return the newly created object instance.</p>
<h4 id="use-validated_data-instead-of-object"><a class="toclink" href="#use-validated_data-instead-of-object">Use <code>.validated_data</code> instead of <code>.object</code>.</a></h4>
<h4 id="use-validated_data-instead-of-object"><code>.object</code>.<a class="toclink" href="#use-validated_data-instead-of-object">Use <code>.validated_data</code> instead of </a></h4>
<p>You must now use the <code>.validated_data</code> attribute if you need to inspect the data before saving, rather than using the <code>.object</code> attribute, which no longer exists.</p>
<p>For example the following code <em>is no longer valid</em>:</p>
<pre><code>if serializer.is_valid():
@ -862,7 +866,7 @@ def all_high_scores(request):
</code></pre>
<hr />
<h2 id="serializer-fields"><a class="toclink" href="#serializer-fields">Serializer fields</a></h2>
<h4 id="the-field-and-readonly-field-classes"><a class="toclink" href="#the-field-and-readonly-field-classes">The <code>Field</code> and <code>ReadOnly</code> field classes.</a></h4>
<h4 id="the-field-and-readonly-field-classes"><code>ReadOnly</code> field classes.<a class="toclink" href="#the-field-and-readonly-field-classes">The <code>Field</code> and </a></h4>
<p>There are some minor tweaks to the field base classes.</p>
<p>Previously we had these two base classes:</p>
<ul>
@ -874,7 +878,7 @@ def all_high_scores(request):
<li><code>Field</code> is the base class for all fields. It does not include any default implementation for either serializing or deserializing data.</li>
<li><code>ReadOnlyField</code> is a concrete implementation for read-only fields that simply returns the attribute value without modification.</li>
</ul>
<h4 id="the-required-allow_null-allow_blank-and-default-arguments"><a class="toclink" href="#the-required-allow_null-allow_blank-and-default-arguments">The <code>required</code>, <code>allow_null</code>, <code>allow_blank</code> and <code>default</code> arguments.</a></h4>
<h4 id="the-required-allow_null-allow_blank-and-default-arguments"><code>allow_null</code>, <code>default</code> arguments.<a class="toclink" href="#the-required-allow_null-allow_blank-and-default-arguments">The <code>required</code>, <code>allow_blank</code> and </a></h4>
<p>REST framework now has more explicit and clear control over validating empty values for fields.</p>
<p>Previously the meaning of the <code>required=False</code> keyword argument was underspecified. In practice its use meant that a field could either be not included in the input, or it could be included, but be <code>None</code> or the empty string.</p>
<p>We now have a better separation, with separate <code>required</code>, <code>allow_null</code> and <code>allow_blank</code> arguments.</p>
@ -984,7 +988,7 @@ This removes some magic and makes it easier and more obvious to move between imp
<p>The following usage will <em>now raise an error</em>:</p>
<pre><code>email = serializers.EmailField(source='email')
</code></pre>
<h4 id="the-uniquevalidator-and-uniquetogethervalidator-classes"><a class="toclink" href="#the-uniquevalidator-and-uniquetogethervalidator-classes">The <code>UniqueValidator</code> and <code>UniqueTogetherValidator</code> classes.</a></h4>
<h4 id="the-uniquevalidator-and-uniquetogethervalidator-classes"><code>UniqueTogetherValidator</code> classes.<a class="toclink" href="#the-uniquevalidator-and-uniquetogethervalidator-classes">The <code>UniqueValidator</code> and </a></h4>
<p>REST framework now provides new validators that allow you to ensure field uniqueness, while still using a completely explicit <code>Serializer</code> class instead of using <code>ModelSerializer</code>.</p>
<p>The <code>UniqueValidator</code> should be applied to a serializer field, and takes a single <code>queryset</code> argument.</p>
<pre><code>from rest_framework import serializers

View File

@ -302,6 +302,10 @@
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../3.5-announcement/">3.5 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.5-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/">
@ -302,6 +302,10 @@
<a href="./">3.4 Announcement</a>
</li>
<li >
<a href="../3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -482,7 +486,7 @@ documentation generation and parameter annotation.</p>
<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>
<td>Built-in support in <code>coreapi</code></td>
</tr>
<tr>
<td><a href="https://openapis.org/specification">Swagger / OpenAPI</a></td>

View File

@ -0,0 +1,673 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<title>3.5 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.5-announcement/" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Django, API, REST, 3.5 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.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>
<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 >
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li class="active" >
<a href="./">3.5 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-35">Django REST framework 3.5</a>
</li>
<li>
<a href="#funding">Funding</a>
</li>
<li>
<a href="#improved-schema-generation">Improved schema generation</a>
</li>
<li>
<a href="#requests-test-client">Requests test client</a>
</li>
<li>
<a href="#core-api-client">Core API client</a>
</li>
<li>
<a href="#live-tests">Live tests</a>
</li>
<li>
<a href="#raml-support">RAML support</a>
</li>
<li>
<a href="#validation-codes">Validation codes</a>
</li>
<li>
<a href="#client-upload-download-support">Client upload &amp; download support</a>
</li>
<li>
<a href="#deprecations">Deprecations</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-35"><a class="toclink" href="#django-rest-framework-35">Django REST framework 3.5</a></h1>
<p>The 3.5 release is the second in a planned series that is addressing schema
generation, hypermedia support, API client libraries, and finally realtime support.</p>
<hr />
<h2 id="funding"><a class="toclink" href="#funding">Funding</a></h2>
<p>The 3.5 release would not have been possible without 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&nbsp;plan</a></strong>.</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>
<li><a href="http://www.machinalis.com/#services" style="background-image: url(https://fund-rest-framework.s3.amazonaws.com/Machinalis130.png)">Machinalis</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">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>, <a href="https://getstream.io/?utm_source=drf&amp;utm_medium=banner&amp;utm_campaign=drf">Stream</a>, and <a href="http://www.machinalis.com/#services">Machinalis</a>.</em></p>
<hr />
<h2 id="improved-schema-generation"><a class="toclink" href="#improved-schema-generation">Improved schema generation</a></h2>
<p>Docstrings on views are now pulled through into schema definitions, allowing
you to <a href="../../api-guide/schemas/#schemas-as-documentation">use the schema definition to document your&nbsp;API</a>.</p>
<p>There is now also a shortcut function, <code>get_schema_view()</code>, which makes it easier to
<a href="../../api-guide/schemas/#the-get_schema_view-shortcut">adding schema views</a> to your API.</p>
<p>For example, to include a swagger schema to your API, you would do the following:</p>
<ul>
<li>
<p>Run <code>pip install django-rest-swagger</code>.</p>
</li>
<li>
<p>Add <code>'rest_framework_swagger'</code> to your <code>INSTALLED_APPS</code> setting.</p>
</li>
<li>
<p>Include the schema view in your URL conf:</p>
</li>
</ul>
<pre><code class="py">from rest_framework.schemas import get_schema_view
from rest_framework_swagger.renderers import OpenAPIRenderer, SwaggerUIRenderer
schema_view = get_schema_view(
title='Example API',
renderer_classes=[OpenAPIRenderer, SwaggerUIRenderer]
)
urlpatterns = [
url(r'^swagger/$', schema_view),
...
]
</code></pre>
<p>There have been a large number of fixes to the schema generation. These should
resolve issues for anyone using the latest version of the <code>django-rest-swagger</code>
package.</p>
<p>Some of these changes do affect the resulting schema structure,
so if you're already using schema generation you should make sure to review
<a href="#deprecations">the deprecation notes</a>, particularly if you're currently using
a dynamic client library to interact with your API.</p>
<p>Finally, we're also now exposing the schema generation as a
<a href="../../api-guide/schemas/#schemagenerator">publicly documented API</a>, allowing you to more easily
override the behaviour.</p>
<h2 id="requests-test-client"><a class="toclink" href="#requests-test-client">Requests test client</a></h2>
<p>You can now test your project using the <code>requests</code> library.</p>
<p>This exposes exactly the same interface as if you were using a standard
requests session instance.</p>
<pre><code>client = RequestsClient()
response = client.get('http://testserver/users/')
assert response.status_code == 200
</code></pre>
<p>Rather than sending any HTTP requests to the network, this interface will
coerce all outgoing requests into WSGI, and call into your application directly.</p>
<h2 id="core-api-client"><a class="toclink" href="#core-api-client">Core API client</a></h2>
<p>You can also now test your project by interacting with it using the <code>coreapi</code>
client library.</p>
<pre><code># Fetch the API schema
client = CoreAPIClient()
schema = client.get('http://testserver/schema/')
# Create a new organisation
params = {'name': 'MegaCorp', 'status': 'active'}
client.action(schema, ['organisations', 'create'], params)
# Ensure that the organisation exists in the listing
data = client.action(schema, ['organisations', 'list'])
assert(len(data) == 1)
assert(data == [{'name': 'MegaCorp', 'status': 'active'}])
</code></pre>
<p>Again, this will call directly into the application using the WSGI interface,
rather than making actual network calls.</p>
<p>This is a good option if you are planning for clients to mainly interact with
your API using the <code>coreapi</code> client library, or some other auto-generated client.</p>
<h2 id="live-tests"><a class="toclink" href="#live-tests">Live tests</a></h2>
<p>One interesting aspect of both the <code>requests</code> client and the <code>coreapi</code> client
is that they allow you to write tests in such a way that they can also be made
to run against a live service.</p>
<p>By switching the WSGI based client instances to actual instances of <code>requests.Session</code>
or <code>coreapi.Client</code> you can have the test cases make actual network calls.</p>
<p>Being able to write test cases that can exercise your staging or production
environment is a powerful tool. However in order to do this, you'll need to pay
close attention to how you handle setup and teardown to ensure a strict isolation
of test data from other live or staging data.</p>
<h2 id="raml-support"><a class="toclink" href="#raml-support">RAML support</a></h2>
<p>We now have preliminary support for <a href="https://github.com/tomchristie/django-rest-raml">RAML documentation generation</a>.</p>
<p><img alt="RAML Example" src="../../img/raml.png" /></p>
<p>Further work on the encoding and documentation generation is planned, in order to
make features such as the 'Try it now' support available at a later date.</p>
<p>This work also now means that you can use the Core API client libraries to interact
with APIs that expose a RAML specification. The <a href="https://github.com/core-api/python-raml-codec">RAML codec</a> gives some examples of
interacting with the Spotify API in this way.</p>
<h2 id="validation-codes"><a class="toclink" href="#validation-codes">Validation codes</a></h2>
<p>Exceptions raised by REST framework now include short code identifiers.
When used together with our customizable error handling, this now allows you to
modify the style of API error messages.</p>
<p>As an example, this allows for the following style of error responses:</p>
<pre><code>{
"message": "You do not have permission to perform this action.",
"code": "permission_denied"
}
</code></pre>
<p>This is particularly useful with validation errors, which use appropriate
codes to identify differing kinds of failure...</p>
<pre><code>{
"name": {"message": "This field is required.", "code": "required"},
"age": {"message": "A valid integer is required.", "code": "invalid"}
}
</code></pre>
<h2 id="client-upload-download-support"><a class="toclink" href="#client-upload-download-support">Client upload &amp; download support</a></h2>
<p>The Python <code>coreapi</code> client library and the Core API command line tool both
now fully support file <a href="http://core-api.github.io/python-client/api-guide/utils/#file">uploads</a> and <a href="http://core-api.github.io/python-client/api-guide/codecs/#downloadcodec">downloads</a>.</p>
<hr />
<h2 id="deprecations"><a class="toclink" href="#deprecations">Deprecations</a></h2>
<h3 id="generating-schemas-from-router"><a class="toclink" href="#generating-schemas-from-router">Generating schemas from Router</a></h3>
<p>The router arguments for generating a schema view, such as <code>schema_title</code>,
are now pending deprecation.</p>
<p>Instead of using <code>DefaultRouter(schema_title='Example API')</code>, you should use
the <code>get_schema_view()</code> function, and include the view in your URL conf.</p>
<p>Make sure to include the view before your router urls. For example:</p>
<pre><code>from rest_framework.schemas import get_schema_view
from my_project.routers import router
schema_view = get_schema_view(title='Example API')
urlpatterns = [
url('^$', schema_view),
url(r'^', include(router.urls)),
]
</code></pre>
<h3 id="schema-path-representations"><a class="toclink" href="#schema-path-representations">Schema path representations</a></h3>
<p>The <code>'pk'</code> identifier in schema paths is now mapped onto the actually model field
name by default. This will typically be <code>'id'</code>.</p>
<p>This gives a better external representation for schemas, with less implementation
detail being exposed. It also reflects the behaviour of using a ModelSerializer
class with <code>fields = '__all__'</code>.</p>
<p>You can revert to the previous behaviour by setting <code>'SCHEMA_COERCE_PATH_PK': False</code>
in the REST framework settings.</p>
<h3 id="schema-action-name-representations"><a class="toclink" href="#schema-action-name-representations">Schema action name representations</a></h3>
<p>The internal <code>retrieve()</code> and <code>destroy()</code> method names are now coerced to an
external representation of <code>read</code> and <code>delete</code>.</p>
<p>You can revert to the previous behaviour by setting <code>'SCHEMA_COERCE_METHOD_NAMES': {}</code>
in the REST framework settings.</p>
<h3 id="djangofilterbackend"><a class="toclink" href="#djangofilterbackend">DjangoFilterBackend</a></h3>
<p>The functionality of the built-in <code>DjangoFilterBackend</code> is now completely
included by the <code>django-filter</code> package.</p>
<p>You should change your imports and REST framework filter settings as follows:</p>
<ul>
<li><code>rest_framework.filters.DjangoFilterBackend</code> becomes <code>django_filters.rest_framework.DjangoFilterBackend</code>.</li>
<li><code>rest_framework.filters.FilterSet</code> becomes <code>django_filters.rest_framework.FilterSet</code>.</li>
</ul>
<p>The existing imports will continue to work but are now pending deprecation.</p>
<h3 id="corejson-media-type"><a class="toclink" href="#corejson-media-type">CoreJSON media type</a></h3>
<p>The media type for <code>CoreJSON</code> is now <code>application/json+coreapi</code>, rather than
the previous <code>application/vnd.json+coreapi</code>. This brings it more into line with
other custom media types, such as those used by Swagger and RAML.</p>
<p>The clients currently accept either media type. The old style-media type will
be deprecated at a later date.</p>
<h3 id="modelserializer-fields-and-exclude"><a class="toclink" href="#modelserializer-fields-and-exclude">ModelSerializer 'fields' and 'exclude'</a></h3>
<p>ModelSerializer and HyperlinkedModelSerializer must include either a fields
option, or an exclude option. The fields = '<strong>all</strong>' shortcut may be used to
explicitly include all fields.</p>
<p>Failing to set either <code>fields</code> or <code>exclude</code> raised a pending deprecation warning
in version 3.3 and raised a deprecation warning in 3.4. Its usage is now mandatory.</p>
<hr />
</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

@ -302,6 +302,10 @@
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -627,7 +631,7 @@ the internal representation of the interface that we are interacting with.</p>
<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>
<p>A codec should be associated with a particular media type, such as <strong>TODO</strong>.</p>
<p>A codec should be associated with a particular media type, such as <code>'application/coreapi+json'</code>.</p>
<p>This media type is used by the server in the response <code>Content-Type</code> header,
in order to indicate what kind of data is being returned in the response.</p>
<h4 id="configuring-codecs"><a class="toclink" href="#configuring-codecs">Configuring codecs</a></h4>

View File

@ -302,6 +302,10 @@
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../3.5-announcement/">3.5 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.4-announcement/">
<a class="repo-link btn btn-inverse btn-small " rel="next" href="../3.5-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>
@ -302,6 +302,10 @@
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../3.5-announcement/">3.5 Announcement</a>
</li>
<li class="active" >
<a href="./">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -378,6 +382,10 @@
<a href="#upgrading">Upgrading</a>
</li>
<li>
<a href="#35x-series">3.5.x series</a>
</li>
<li>
<a href="#34x-series">3.4.x series</a>
</li>
@ -445,6 +453,10 @@
<pre><code>pip freeze | grep djangorestframework
</code></pre>
<hr />
<h2 id="35x-series"><a class="toclink" href="#35x-series">3.5.x series</a></h2>
<h3 id="350"><a class="toclink" href="#350">3.5.0</a></h3>
<p><strong>Date</strong>: <a href="https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.5.0+Release%22">20th October 2016</a></p>
<hr />
<h2 id="34x-series"><a class="toclink" href="#34x-series">3.4.x series</a></h2>
<h3 id="347"><a class="toclink" href="#347">3.4.7</a></h3>
<p><strong>Date</strong>: <a href="https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.4.7+Release%22">21st September 2016</a></p>

View File

@ -302,6 +302,10 @@
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -603,15 +607,6 @@ You probably want to also tag the version now:
<li><a href="http://richardtier.com/2014/02/25/django-rest-framework-user-endpoint/">Django Rest Framework User Endpoint</a></li>
<li><a href="http://richardtier.com/2014/03/06/110/">Check credentials using Django Rest Framework</a></li>
<li><a href="https://teamtreehouse.com/library/django-rest-framework">Django REST Framework course</a></li>
<li><a href="https://makina-corpus.com/blog/metier/2015/django-rest-framework-les-serializer-et-les-exceptions-partie-1">[Français] Django Rest Framework : les Serializer et les exceptions</a></li>
<li><a href="https://makina-corpus.com/blog/metier/2015/django-rest-framework-les-viewset-partie-2">[Français] Django Rest Framework : les Viewset</a></li>
<li><a href="https://makina-corpus.com/blog/metier/2016/django-rest-framework-fonctionnement-des-routeurs-partie-3">[Français] Django Rest Framework : fonctionnement des routeurs</a></li>
<li><a href="https://makina-corpus.com/blog/metier/2016/django-rest-framework-integration-des-routeurs-partie-4">[Français] Django Rest Framework : intégration des routeurs</a></li>
<li><a href="https://makina-corpus.com/blog/metier/2016/django-rest-framework-personnalisation-des-routeurs-partie-5">[Français] Django Rest Framework : personnalisation des routeurs</a></li>
<li><a href="https://makina-corpus.com/blog/metier/2016/django-rest-framework-la-negociation-de-contenu-partie-6">[Français] Django Rest Framework : négociation de contenu</a></li>
<li><a href="https://makina-corpus.com/blog/metier/2016/django-rest-framework-le-versioning-avec-drf-partie-7">[Français] Django Rest Framework : versioning avec DRF</a></li>
<li><a href="https://makina-corpus.com/blog/metier/2016/django-rest-framework-les-tests-partie-8">[Français] Django Rest Framework : les tests</a></li>
<li><a href="https://makina-corpus.com/blog/metier/2016/django-rest-framework-le-versioning-pour-les-api-rest-hors-serie">[Français] Django Rest Framework : versioning pour les API REST</a></li>
</ul>
<h3 id="videos"><a class="toclink" href="#videos">Videos</a></h3>
<ul>

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -636,12 +640,12 @@ def snippet_list(request):
<p>Note that because we want to be able to POST to this view from clients that won't have a CSRF token we need to mark the view as <code>csrf_exempt</code>. This isn't something that you'd normally want to do, and REST framework views actually use more sensible behavior than this, but it'll do for our purposes right now.</p>
<p>We'll also need a view which corresponds to an individual snippet, and can be used to retrieve, update or delete the snippet.</p>
<pre><code>@csrf_exempt
def snippet_detail(request, id):
def snippet_detail(request, pk):
"""
Retrieve, update or delete a code snippet.
"""
try:
snippet = Snippet.objects.get(id=id)
snippet = Snippet.objects.get(pk=pk)
except Snippet.DoesNotExist:
return HttpResponse(status=404)
@ -667,7 +671,7 @@ from snippets import views
urlpatterns = [
url(r'^snippets/$', views.snippet_list),
url(r'^snippets/(?P&lt;id&gt;[0-9]+)/$', views.snippet_detail),
url(r'^snippets/(?P&lt;pk&gt;[0-9]+)/$', views.snippet_detail),
]
</code></pre>
<p>We also need to wire up the root urlconf, in the <code>tutorial/urls.py</code> file, to include our snippet app's URLs.</p>

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -465,12 +469,12 @@ def snippet_list(request):
<p>Our instance view is an improvement over the previous example. It's a little more concise, and the code now feels very similar to if we were working with the Forms API. We're also using named status codes, which makes the response meanings more obvious.</p>
<p>Here is the view for an individual snippet, in the <code>views.py</code> module.</p>
<pre><code>@api_view(['GET', 'PUT', 'DELETE'])
def snippet_detail(request, id):
def snippet_detail(request, pk):
"""
Retrieve, update or delete a snippet instance.
"""
try:
snippet = Snippet.objects.get(id=id)
snippet = Snippet.objects.get(pk=pk)
except Snippet.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
@ -497,7 +501,7 @@ def snippet_detail(request, id):
<pre><code>def snippet_list(request, format=None):
</code></pre>
<p>and</p>
<pre><code>def snippet_detail(request, id, format=None):
<pre><code>def snippet_detail(request, pk, format=None):
</code></pre>
<p>Now update the <code>urls.py</code> file slightly, to append a set of <code>format_suffix_patterns</code> in addition to the existing URLs.</p>
<pre><code>from django.conf.urls import url
@ -506,7 +510,7 @@ from snippets import views
urlpatterns = [
url(r'^snippets/$', views.snippet_list),
url(r'^snippets/(?P&lt;id&gt;[0-9]+)$', views.snippet_detail),
url(r'^snippets/(?P&lt;pk&gt;[0-9]+)$', views.snippet_detail),
]
urlpatterns = format_suffix_patterns(urlpatterns)

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -426,27 +430,27 @@ class SnippetList(APIView):
"""
Retrieve, update or delete a snippet instance.
"""
def get_object(self, id):
def get_object(self, pk):
try:
return Snippet.objects.get(id=id)
return Snippet.objects.get(pk=pk)
except Snippet.DoesNotExist:
raise Http404
def get(self, request, id, format=None):
snippet = self.get_object(id)
def get(self, request, pk, format=None):
snippet = self.get_object(pk)
serializer = SnippetSerializer(snippet)
return Response(serializer.data)
def put(self, request, id, format=None):
snippet = self.get_object(id)
def put(self, request, pk, format=None):
snippet = self.get_object(pk)
serializer = SnippetSerializer(snippet, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, id, format=None):
snippet = self.get_object(id)
def delete(self, request, pk, format=None):
snippet = self.get_object(pk)
snippet.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
</code></pre>
@ -458,7 +462,7 @@ from snippets import views
urlpatterns = [
url(r'^snippets/$', views.SnippetList.as_view()),
url(r'^snippets/(?P&lt;id&gt;[0-9]+)/$', views.SnippetDetail.as_view()),
url(r'^snippets/(?P&lt;pk&gt;[0-9]+)/$', views.SnippetDetail.as_view()),
]
urlpatterns = format_suffix_patterns(urlpatterns)

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -492,7 +496,7 @@ class UserDetail(generics.RetrieveAPIView):
</code></pre>
<p>Finally we need to add those views into the API, by referencing them from the URL conf. Add the following to the patterns in <code>urls.py</code>.</p>
<pre><code>url(r'^users/$', views.UserList.as_view()),
url(r'^users/(?P&lt;id&gt;[0-9]+)/$', views.UserDetail.as_view()),
url(r'^users/(?P&lt;pk&gt;[0-9]+)/$', views.UserDetail.as_view()),
</code></pre>
<h2 id="associating-snippets-with-users"><a class="toclink" href="#associating-snippets-with-users">Associating Snippets with Users</a></h2>
<p>Right now, if we created a code snippet, there'd be no way of associating the user that created the snippet, with the snippet instance. The user isn't sent as part of the serialized representation, but is instead a property of the incoming request.</p>

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -443,7 +447,7 @@ We'll add a url pattern for our new API root in <code>snippets/urls.py</code>:</
<pre><code>url(r'^$', views.api_root),
</code></pre>
<p>And then add a url pattern for the snippet highlights:</p>
<pre><code>url(r'^snippets/(?P&lt;id&gt;[0-9]+)/highlight/$', views.SnippetHighlight.as_view()),
<pre><code>url(r'^snippets/(?P&lt;pk&gt;[0-9]+)/highlight/$', views.SnippetHighlight.as_view()),
</code></pre>
<h2 id="hyperlinking-our-api"><a class="toclink" href="#hyperlinking-our-api">Hyperlinking our API</a></h2>
<p>Dealing with relationships between entities is one of the more challenging aspects of Web API design. There are a number of different ways that we might choose to represent a relationship:</p>
@ -503,16 +507,16 @@ urlpatterns = format_suffix_patterns([
url(r'^snippets/$',
views.SnippetList.as_view(),
name='snippet-list'),
url(r'^snippets/(?P&lt;id&gt;[0-9]+)/$',
url(r'^snippets/(?P&lt;pk&gt;[0-9]+)/$',
views.SnippetDetail.as_view(),
name='snippet-detail'),
url(r'^snippets/(?P&lt;id&gt;[0-9]+)/highlight/$',
url(r'^snippets/(?P&lt;pk&gt;[0-9]+)/highlight/$',
views.SnippetHighlight.as_view(),
name='snippet-highlight'),
url(r'^users/$',
views.UserList.as_view(),
name='user-list'),
url(r'^users/(?P&lt;id&gt;[0-9]+)/$',
url(r'^users/(?P&lt;pk&gt;[0-9]+)/$',
views.UserDetail.as_view(),
name='user-detail')
])

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>
@ -439,7 +443,7 @@ class SnippetViewSet(viewsets.ModelViewSet):
</code></pre>
<p>This time we've used the <code>ModelViewSet</code> class in order to get the complete set of default read and write operations.</p>
<p>Notice that we've also used the <code>@detail_route</code> decorator to create a custom action, named <code>highlight</code>. This decorator can be used to add any custom endpoints that don't fit into the standard <code>create</code>/<code>update</code>/<code>delete</code> style.</p>
<p>Custom actions which use the <code>@detail_route</code> decorator will respond to <code>GET</code> requests. We can use the <code>methods</code> argument if we wanted an action that responded to <code>POST</code> requests.</p>
<p>Custom actions which use the <code>@detail_route</code> decorator will respond to <code>GET</code> requests by default. We can use the <code>methods</code> argument if we wanted an action that responded to <code>POST</code> requests.</p>
<p>The URLs for custom actions by default depend on the method name itself. If you want to change the way url should be constructed, you can include url_path as a decorator keyword argument.</p>
<h2 id="binding-viewsets-to-urls-explicitly"><a class="toclink" href="#binding-viewsets-to-urls-explicitly">Binding ViewSets to URLs explicitly</a></h2>
<p>The handler methods only get bound to the actions when we define the URLConf.
@ -473,10 +477,10 @@ user_detail = UserViewSet.as_view({
<pre><code>urlpatterns = format_suffix_patterns([
url(r'^$', api_root),
url(r'^snippets/$', snippet_list, name='snippet-list'),
url(r'^snippets/(?P&lt;id&gt;[0-9]+)/$', snippet_detail, name='snippet-detail'),
url(r'^snippets/(?P&lt;id&gt;[0-9]+)/highlight/$', snippet_highlight, name='snippet-highlight'),
url(r'^snippets/(?P&lt;pk&gt;[0-9]+)/$', snippet_detail, name='snippet-detail'),
url(r'^snippets/(?P&lt;pk&gt;[0-9]+)/highlight/$', snippet_highlight, name='snippet-highlight'),
url(r'^users/$', user_list, name='user-list'),
url(r'^users/(?P&lt;id&gt;[0-9]+)/$', user_detail, name='user-detail')
url(r'^users/(?P&lt;pk&gt;[0-9]+)/$', user_detail, name='user-detail')
])
</code></pre>
<h2 id="using-routers"><a class="toclink" href="#using-routers">Using Routers</a></h2>

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>

View File

@ -302,6 +302,10 @@
<a href="../../topics/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../topics/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../topics/kickstarter-announcement/">Kickstarter Announcement</a>
</li>