Commit dd14c6c8 by Tom Christie

Latest docs release

parent ce165805
...@@ -206,6 +206,7 @@ a.fusion-poweredby { ...@@ -206,6 +206,7 @@ a.fusion-poweredby {
<li><a href="#json-web-token-authentication">JSON Web Token Authentication</a></li> <li><a href="#json-web-token-authentication">JSON Web Token Authentication</a></li>
<li><a href="#hawk-http-authentication">Hawk HTTP Authentication</a></li> <li><a href="#hawk-http-authentication">Hawk HTTP Authentication</a></li>
<li><a href="#http-signature-authentication">HTTP Signature Authentication</a></li> <li><a href="#http-signature-authentication">HTTP Signature Authentication</a></li>
<li><a href="#djoser">Djoser</a></li>
<div class="promo"> <div class="promo">
...@@ -337,12 +338,13 @@ print token.key ...@@ -337,12 +338,13 @@ print token.key
<hr /> <hr />
<h4 id="generating-tokens">Generating Tokens</h4> <h4 id="generating-tokens">Generating Tokens</h4>
<p>If you want every user to have an automatically generated Token, you can simply catch the User's <code>post_save</code> signal.</p> <p>If you want every user to have an automatically generated Token, you can simply catch the User's <code>post_save</code> signal.</p>
<pre class="prettyprint lang-py"><code>from django.contrib.auth import get_user_model <pre class="prettyprint lang-py"><code>from django.conf import settings
from django.contrib.auth import get_user_model
from django.db.models.signals import post_save from django.db.models.signals import post_save
from django.dispatch import receiver from django.dispatch import receiver
from rest_framework.authtoken.models import Token from rest_framework.authtoken.models import Token
@receiver(post_save, sender=get_user_model()) @receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs): def create_auth_token(sender, instance=None, created=False, **kwargs):
if created: if created:
Token.objects.create(user=instance) Token.objects.create(user=instance)
...@@ -356,9 +358,10 @@ for user in User.objects.all(): ...@@ -356,9 +358,10 @@ for user in User.objects.all():
Token.objects.get_or_create(user=user) Token.objects.get_or_create(user=user)
</code></pre> </code></pre>
<p>When using <code>TokenAuthentication</code>, you may want to provide a mechanism for clients to obtain a token given the username and password. REST framework provides a built-in view to provide this behavior. To use it, add the <code>obtain_auth_token</code> view to your URLconf:</p> <p>When using <code>TokenAuthentication</code>, you may want to provide a mechanism for clients to obtain a token given the username and password. REST framework provides a built-in view to provide this behavior. To use it, add the <code>obtain_auth_token</code> view to your URLconf:</p>
<pre class="prettyprint lang-py"><code>urlpatterns += patterns('', <pre class="prettyprint lang-py"><code>from rest_framework.authtoken import views
url(r'^api-token-auth/', 'rest_framework.authtoken.views.obtain_auth_token') urlpatterns += [
) url(r'^api-token-auth/', views.obtain_auth_token)
]
</code></pre> </code></pre>
<p>Note that the URL part of the pattern can be whatever you want to use.</p> <p>Note that the URL part of the pattern can be whatever you want to use.</p>
<p>The <code>obtain_auth_token</code> view will return a JSON response when valid <code>username</code> and <code>password</code> fields are POSTed to the view using form data or JSON:</p> <p>The <code>obtain_auth_token</code> view will return a JSON response when valid <code>username</code> and <code>password</code> fields are POSTed to the view using form data or JSON:</p>
...@@ -508,6 +511,8 @@ class ExampleAuthentication(authentication.BaseAuthentication): ...@@ -508,6 +511,8 @@ class ExampleAuthentication(authentication.BaseAuthentication):
<p>The <a href="http://hawkrest.readthedocs.org/en/latest/">HawkREST</a> library builds on the <a href="http://mohawk.readthedocs.org/en/latest/">Mohawk</a> library to let you work with <a href="https://github.com/hueniverse/hawk">Hawk</a> signed requests and responses in your API. <a href="https://github.com/hueniverse/hawk">Hawk</a> lets two parties securely communicate with each other using messages signed by a shared key. It is based on <a href="http://tools.ietf.org/html/draft-hammer-oauth-v2-mac-token-05">HTTP MAC access authentication</a> (which was based on parts of <a href="http://oauth.net/core/1.0a">OAuth 1.0</a>).</p> <p>The <a href="http://hawkrest.readthedocs.org/en/latest/">HawkREST</a> library builds on the <a href="http://mohawk.readthedocs.org/en/latest/">Mohawk</a> library to let you work with <a href="https://github.com/hueniverse/hawk">Hawk</a> signed requests and responses in your API. <a href="https://github.com/hueniverse/hawk">Hawk</a> lets two parties securely communicate with each other using messages signed by a shared key. It is based on <a href="http://tools.ietf.org/html/draft-hammer-oauth-v2-mac-token-05">HTTP MAC access authentication</a> (which was based on parts of <a href="http://oauth.net/core/1.0a">OAuth 1.0</a>).</p>
<h2 id="http-signature-authentication">HTTP Signature Authentication</h2> <h2 id="http-signature-authentication">HTTP Signature Authentication</h2>
<p>HTTP Signature (currently a <a href="https://datatracker.ietf.org/doc/draft-cavage-http-signatures/">IETF draft</a>) provides a way to achieve origin authentication and message integrity for HTTP messages. Similar to <a href="http://docs.aws.amazon.com/general/latest/gr/signature-version-4.html">Amazon's HTTP Signature scheme</a>, used by many of its services, it permits stateless, per-request authentication. <a href="https://github.com/etoccalino/">Elvio Toccalino</a> maintains the <a href="https://github.com/etoccalino/django-rest-framework-httpsignature">djangorestframework-httpsignature</a> package which provides an easy to use HTTP Signature Authentication mechanism.</p> <p>HTTP Signature (currently a <a href="https://datatracker.ietf.org/doc/draft-cavage-http-signatures/">IETF draft</a>) provides a way to achieve origin authentication and message integrity for HTTP messages. Similar to <a href="http://docs.aws.amazon.com/general/latest/gr/signature-version-4.html">Amazon's HTTP Signature scheme</a>, used by many of its services, it permits stateless, per-request authentication. <a href="https://github.com/etoccalino/">Elvio Toccalino</a> maintains the <a href="https://github.com/etoccalino/django-rest-framework-httpsignature">djangorestframework-httpsignature</a> package which provides an easy to use HTTP Signature Authentication mechanism.</p>
<h2 id="djoser">Djoser</h2>
<p><a href="https://github.com/sunscrapers/djoser">Djoser</a> library provides a set of views to handle basic actions such as registration, login, logout, password reset and account activation. The package works with a custom user model and it uses token based authentication. This is a ready to use REST implementation of Django authentication system.</p>
</div><!--/span--> </div><!--/span-->
</div><!--/row--> </div><!--/row-->
</div><!--/.fluid-container--> </div><!--/.fluid-container-->
......
...@@ -219,12 +219,13 @@ used all the time.</p> ...@@ -219,12 +219,13 @@ used all the time.</p>
</ul> </ul>
<p>Example:</p> <p>Example:</p>
<pre class="prettyprint lang-py"><code>from rest_framework.urlpatterns import format_suffix_patterns <pre class="prettyprint lang-py"><code>from rest_framework.urlpatterns import format_suffix_patterns
from blog import views
urlpatterns = patterns('blog.views', urlpatterns = [
url(r'^/$', 'api_root'), url(r'^/$', views.apt_root),
url(r'^comments/$', 'comment_list'), url(r'^comments/$', views.comment_list),
url(r'^comments/(?P&lt;pk&gt;[0-9]+)/$', 'comment_detail') url(r'^comments/(?P&lt;pk&gt;[0-9]+)/$', views.comment_detail)
) ]
urlpatterns = format_suffix_patterns(urlpatterns, allowed=['json', 'html']) urlpatterns = format_suffix_patterns(urlpatterns, allowed=['json', 'html'])
</code></pre> </code></pre>
......
...@@ -253,7 +253,7 @@ a.fusion-poweredby { ...@@ -253,7 +253,7 @@ a.fusion-poweredby {
<h2 id="requirements">Requirements</h2> <h2 id="requirements">Requirements</h2>
<p>REST framework requires the following:</p> <p>REST framework requires the following:</p>
<ul> <ul>
<li>Python (2.6.5+, 2.7, 3.2, 3.3)</li> <li>Python (2.6.5+, 2.7, 3.2, 3.3, 3.4)</li>
<li>Django (1.4.2+, 1.5, 1.6, 1.7)</li> <li>Django (1.4.2+, 1.5, 1.6, 1.7)</li>
</ul> </ul>
<p>The following packages are optional:</p> <p>The following packages are optional:</p>
...@@ -283,10 +283,10 @@ pip install django-filter # Filtering support ...@@ -283,10 +283,10 @@ pip install django-filter # Filtering support
) )
</code></pre> </code></pre>
<p>If you're intending to use the browsable API you'll probably also want to add REST framework's login and logout views. Add the following to your root <code>urls.py</code> file.</p> <p>If you're intending to use the browsable API you'll probably also want to add REST framework's login and logout views. Add the following to your root <code>urls.py</code> file.</p>
<pre class="prettyprint lang-py"><code>urlpatterns = patterns('', <pre class="prettyprint lang-py"><code>urlpatterns = [
... ...
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')) url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
) ]
</code></pre> </code></pre>
<p>Note that the URL path can be whatever you want, but you must include <code>'rest_framework.urls'</code> with the <code>'rest_framework'</code> namespace.</p> <p>Note that the URL path can be whatever you want, but you must include <code>'rest_framework.urls'</code> with the <code>'rest_framework'</code> namespace.</p>
<h2 id="example">Example</h2> <h2 id="example">Example</h2>
......
...@@ -223,7 +223,7 @@ a.fusion-poweredby { ...@@ -223,7 +223,7 @@ a.fusion-poweredby {
<pre class="prettyprint lang-py"><code>""" <pre class="prettyprint lang-py"><code>"""
A REST framework API for viewing and editing users and groups. A REST framework API for viewing and editing users and groups.
""" """
from django.conf.urls.defaults import url, patterns, include from django.conf.urls.defaults import url, include
from django.contrib.auth.models import User, Group from django.contrib.auth.models import User, Group
from rest_framework import viewsets, routers from rest_framework import viewsets, routers
...@@ -244,10 +244,10 @@ router.register(r'groups', GroupViewSet) ...@@ -244,10 +244,10 @@ router.register(r'groups', GroupViewSet)
# Wire up our API using automatic URL routing. # Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browseable API. # Additionally, we include login URLs for the browseable API.
urlpatterns = patterns('', urlpatterns = [
url(r'^', include(router.urls)), url(r'^', include(router.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')) url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
) ]
</code></pre> </code></pre>
<p>The best place to get started with ViewSets and Routers is to take a look at the <a href="../tutorial/6-viewsets-and-routers">newest section in the tutorial</a>, which demonstrates their usage.</p> <p>The best place to get started with ViewSets and Routers is to take a look at the <a href="../tutorial/6-viewsets-and-routers">newest section in the tutorial</a>, which demonstrates their usage.</p>
<h2 id="simpler-views">Simpler views</h2> <h2 id="simpler-views">Simpler views</h2>
......
...@@ -295,8 +295,8 @@ The lowest supported version of Django is now 1.4.2.</p> ...@@ -295,8 +295,8 @@ The lowest supported version of Django is now 1.4.2.</p>
</ul> </ul>
<h2 id="other-features">Other features</h2> <h2 id="other-features">Other features</h2>
<p>There are also a number of other features and bugfixes as <a href="release-notes#240">listed in the release notes</a>. In particular these include:</p> <p>There are also a number of other features and bugfixes as <a href="release-notes#240">listed in the release notes</a>. In particular these include:</p>
<p><a href="../api-guide/settings/#view-names-and-descriptions">Customizable view name and description functions</a> for use with the browsable API, by using the <code>VIEW_NAME_FUNCTION</code> and <code>VIEW_DESCRIPTION_FUNCTION</code> settings.</p> <p><a href="../api-guide/settings#view-names-and-descriptions">Customizable view name and description functions</a> for use with the browsable API, by using the <code>VIEW_NAME_FUNCTION</code> and <code>VIEW_DESCRIPTION_FUNCTION</code> settings.</p>
<p>Smarter <a href="../api-guide/throttling/#how-clients-are-identified">client IP identification for throttling</a>, with the addition of the <code>NUM_PROXIES</code> setting.</p> <p>Smarter <a href="../api-guide/throttling#how-clients-are-identified">client IP identification for throttling</a>, with the addition of the <code>NUM_PROXIES</code> setting.</p>
<p>Added the standardized <code>Retry-After</code> header to throttled responses, as per <a href="http://tools.ietf.org/html/rfc6585">RFC 6585</a>. This should now be used in preference to the custom <code>X-Throttle-Wait-Seconds</code> header which will be fully deprecated in 3.0.</p> <p>Added the standardized <code>Retry-After</code> header to throttled responses, as per <a href="http://tools.ietf.org/html/rfc6585">RFC 6585</a>. This should now be used in preference to the custom <code>X-Throttle-Wait-Seconds</code> header which will be fully deprecated in 3.0.</p>
<h2 id="deprecations">Deprecations</h2> <h2 id="deprecations">Deprecations</h2>
<p>All API changes in 2.3 that previously raised <code>PendingDeprecationWarning</code> will now raise a <code>DeprecationWarning</code>, which is loud by default.</p> <p>All API changes in 2.3 that previously raised <code>PendingDeprecationWarning</code> will now raise a <code>DeprecationWarning</code>, which is loud by default.</p>
......
...@@ -356,7 +356,8 @@ More text... ...@@ -356,7 +356,8 @@ More text...
<p>If you have some functionality that you would like to implement as a third party package it's worth contacting the <a href="https://groups.google.com/forum/?fromgroups#!forum/django-rest-framework">discussion group</a> as others may be willing to get involved. We strongly encourage third party package development and will always try to prioritize time spent helping their development, documentation and packaging.</p> <p>If you have some functionality that you would like to implement as a third party package it's worth contacting the <a href="https://groups.google.com/forum/?fromgroups#!forum/django-rest-framework">discussion group</a> as others may be willing to get involved. We strongly encourage third party package development and will always try to prioritize time spent helping their development, documentation and packaging.</p>
<p>We recommend the <a href="https://github.com/dabapps/django-reusable-app"><code>django-reusable-app</code></a> template as a good resource for getting up and running with implementing a third party Django package.</p> <p>We recommend the <a href="https://github.com/dabapps/django-reusable-app"><code>django-reusable-app</code></a> template as a good resource for getting up and running with implementing a third party Django package.</p>
<h2 id="linking-to-your-package">Linking to your package</h2> <h2 id="linking-to-your-package">Linking to your package</h2>
<p>Once your package is decently documented and available on PyPI open a pull request or issue, and we'll add a link to it from the main REST framework documentation.</p> <p>Once your package is decently documented and available on PyPI open a pull request or issue, and we'll add a link to it from the main REST framework documentation. You can add your package under <strong>Third party packages</strong> of the API Guide section that best applies, like <a href="../api-guide/authentication">Authentication</a> or <a href="../api-guide/permissions">Permissions</a>. You can also link your package under the <a href="third-party-resources">Third Party Resources</a> section.</p>
<p>We also suggest adding it to the <a href="https://www.djangopackages.com/grids/g/django-rest-framework/">REST Framework</a> grid on Django Packages.</p>
</div><!--/span--> </div><!--/span-->
</div><!--/row--> </div><!--/row-->
</div><!--/.fluid-container--> </div><!--/.fluid-container-->
......
...@@ -242,6 +242,15 @@ a.fusion-poweredby { ...@@ -242,6 +242,15 @@ a.fusion-poweredby {
</code></pre> </code></pre>
<hr /> <hr />
<h2 id="24x-series">2.4.x series</h2> <h2 id="24x-series">2.4.x series</h2>
<h3 id="244">2.4.4</h3>
<p><strong>Date</strong>: <a href="https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%222.4.4+Release%22+">3rd November 2014</a>.</p>
<ul>
<li><strong>Security fix</strong>: Escape URLs when replacing <code>format=</code> query parameter, as used in dropdown on <code>GET</code> button in browsable API to allow explicit selection of JSON vs HTML output.</li>
<li>Maintain ordering of URLs in API root view for <code>DefaultRouter</code>.</li>
<li>Fix <code>follow=True</code> in <code>APIRequestFactory</code></li>
<li>Resolve issue with invalid <code>read_only=True</code>, <code>required=True</code> fields being automatically generated by <code>ModelSerializer</code> in some cases.</li>
<li>Resolve issue with <code>OPTIONS</code> requests returning incorrect information for views using <code>get_serializer_class</code> to dynamically determine serializer based on request method. </li>
</ul>
<h3 id="243">2.4.3</h3> <h3 id="243">2.4.3</h3>
<p><strong>Date</strong>: <a href="https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%222.4.3+Release%22+">19th September 2014</a>.</p> <p><strong>Date</strong>: <a href="https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%222.4.3+Release%22+">19th September 2014</a>.</p>
<ul> <ul>
......
...@@ -214,6 +214,7 @@ a.fusion-poweredby { ...@@ -214,6 +214,7 @@ a.fusion-poweredby {
<li><a href="https://github.com/GetBlimp/django-rest-framework-jwt">djangorestframework-jwt</a> - Provides JSON Web Token Authentication support.</li> <li><a href="https://github.com/GetBlimp/django-rest-framework-jwt">djangorestframework-jwt</a> - Provides JSON Web Token Authentication support.</li>
<li><a href="https://github.com/kumar303/hawkrest">hawkrest</a> - Provides Hawk HTTP Authorization.</li> <li><a href="https://github.com/kumar303/hawkrest">hawkrest</a> - Provides Hawk HTTP Authorization.</li>
<li><a href="https://github.com/etoccalino/django-rest-framework-httpsignature">djangorestframework-httpsignature</a> - Provides an easy to use HTTP Signature Authentication mechanism.</li> <li><a href="https://github.com/etoccalino/django-rest-framework-httpsignature">djangorestframework-httpsignature</a> - Provides an easy to use HTTP Signature Authentication mechanism.</li>
<li><a href="https://github.com/sunscrapers/djoser">djoser</a> - Provides a set of views to handle basic actions such as registration, login, logout, password reset and account activation.</li>
</ul> </ul>
<h3 id="permissions">Permissions</h3> <h3 id="permissions">Permissions</h3>
<ul> <ul>
......
...@@ -256,9 +256,9 @@ cd tutorial ...@@ -256,9 +256,9 @@ cd tutorial
) )
</code></pre> </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> <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>
<pre class="prettyprint lang-py"><code>urlpatterns = patterns('', <pre class="prettyprint lang-py"><code>urlpatterns = [
url(r'^', include('snippets.urls')), url(r'^', include('snippets.urls')),
) ]
</code></pre> </code></pre>
<p>Okay, we're ready to roll.</p> <p>Okay, we're ready to roll.</p>
<h2 id="creating-a-model-to-work-with">Creating a model to work with</h2> <h2 id="creating-a-model-to-work-with">Creating a model to work with</h2>
...@@ -459,11 +459,12 @@ def snippet_detail(request, pk): ...@@ -459,11 +459,12 @@ def snippet_detail(request, pk):
</code></pre> </code></pre>
<p>Finally we need to wire these views up. Create the <code>snippets/urls.py</code> file:</p> <p>Finally we need to wire these views up. Create the <code>snippets/urls.py</code> file:</p>
<pre class="prettyprint lang-py"><code>from django.conf.urls import patterns, url <pre class="prettyprint lang-py"><code>from django.conf.urls import patterns, url
from snippets import views
urlpatterns = patterns('snippets.views', urlpatterns = [
url(r'^snippets/$', 'snippet_list'), url(r'^snippets/$', views.snippet_list),
url(r'^snippets/(?P&lt;pk&gt;[0-9]+)/$', 'snippet_detail'), url(r'^snippets/(?P&lt;pk&gt;[0-9]+)/$', views.snippet_detail),
) ]
</code></pre> </code></pre>
<p>It's worth noting that there are a couple of edge cases we're not dealing with properly at the moment. If we send malformed <code>json</code>, or if a request is made with a method that the view doesn't handle, then we'll end up with a 500 "server error" response. Still, this'll do for now.</p> <p>It's worth noting that there are a couple of edge cases we're not dealing with properly at the moment. If we send malformed <code>json</code>, or if a request is made with a method that the view doesn't handle, then we'll end up with a 500 "server error" response. Still, this'll do for now.</p>
<h2 id="testing-our-first-attempt-at-a-web-api">Testing our first attempt at a Web API</h2> <h2 id="testing-our-first-attempt-at-a-web-api">Testing our first attempt at a Web API</h2>
......
...@@ -294,11 +294,12 @@ def snippet_detail(request, pk): ...@@ -294,11 +294,12 @@ def snippet_detail(request, pk):
<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> <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 class="prettyprint lang-py"><code>from django.conf.urls import patterns, url <pre class="prettyprint lang-py"><code>from django.conf.urls import patterns, url
from rest_framework.urlpatterns import format_suffix_patterns from rest_framework.urlpatterns import format_suffix_patterns
from snippets import views
urlpatterns = patterns('snippets.views', urlpatterns = [
url(r'^snippets/$', 'snippet_list'), url(r'^snippets/$', views.snippet_list),
url(r'^snippets/(?P&lt;pk&gt;[0-9]+)$', 'snippet_detail'), url(r'^snippets/(?P&lt;pk&gt;[0-9]+)$', views.snippet_detail),
) ]
urlpatterns = format_suffix_patterns(urlpatterns) urlpatterns = format_suffix_patterns(urlpatterns)
</code></pre> </code></pre>
......
...@@ -263,10 +263,10 @@ class SnippetList(APIView): ...@@ -263,10 +263,10 @@ class SnippetList(APIView):
from rest_framework.urlpatterns import format_suffix_patterns from rest_framework.urlpatterns import format_suffix_patterns
from snippets import views from snippets import views
urlpatterns = patterns('', urlpatterns = [
url(r'^snippets/$', views.SnippetList.as_view()), url(r'^snippets/$', views.SnippetList.as_view()),
url(r'^snippets/(?P&lt;pk&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) urlpatterns = format_suffix_patterns(urlpatterns)
</code></pre> </code></pre>
......
...@@ -311,10 +311,10 @@ url(r'^users/(?P&lt;pk&gt;[0-9]+)/$', views.UserDetail.as_view()), ...@@ -311,10 +311,10 @@ url(r'^users/(?P&lt;pk&gt;[0-9]+)/$', views.UserDetail.as_view()),
<pre class="prettyprint lang-py"><code>from django.conf.urls import include <pre class="prettyprint lang-py"><code>from django.conf.urls import include
</code></pre> </code></pre>
<p>And, at the end of the file, add a pattern to include the login and logout views for the browsable API.</p> <p>And, at the end of the file, add a pattern to include the login and logout views for the browsable API.</p>
<pre class="prettyprint lang-py"><code>urlpatterns += patterns('', <pre class="prettyprint lang-py"><code>urlpatterns += [
url(r'^api-auth/', include('rest_framework.urls', url(r'^api-auth/', include('rest_framework.urls',
namespace='rest_framework')), namespace='rest_framework')),
) ]
</code></pre> </code></pre>
<p>The <code>r'^api-auth/'</code> part of pattern can actually be whatever URL you want to use. The only restriction is that the included urls must use the <code>'rest_framework'</code> namespace.</p> <p>The <code>r'^api-auth/'</code> part of pattern can actually be whatever URL you want to use. The only restriction is that the included urls must use the <code>'rest_framework'</code> namespace.</p>
<p>Now if you open up the browser again and refresh the page you'll see a 'Login' link in the top right of the page. If you log in as one of the users you created earlier, you'll be able to create code snippets again.</p> <p>Now if you open up the browser again and refresh the page you'll see a 'Login' link in the top right of the page. If you log in as one of the users you created earlier, you'll be able to create code snippets again.</p>
......
...@@ -293,8 +293,8 @@ class UserSerializer(serializers.HyperlinkedModelSerializer): ...@@ -293,8 +293,8 @@ class UserSerializer(serializers.HyperlinkedModelSerializer):
</ul> </ul>
<p>After adding all those names into our URLconf, our final <code>snippets/urls.py</code> file should look something like this:</p> <p>After adding all those names into our URLconf, our final <code>snippets/urls.py</code> file should look something like this:</p>
<pre class="prettyprint lang-py"><code># API endpoints <pre class="prettyprint lang-py"><code># API endpoints
urlpatterns = format_suffix_patterns(patterns('snippets.views', urlpatterns = format_suffix_patterns([
url(r'^$', 'api_root'), url(r'^$', views.api_root),
url(r'^snippets/$', url(r'^snippets/$',
views.SnippetList.as_view(), views.SnippetList.as_view(),
name='snippet-list'), name='snippet-list'),
...@@ -310,13 +310,13 @@ urlpatterns = format_suffix_patterns(patterns('snippets.views', ...@@ -310,13 +310,13 @@ urlpatterns = format_suffix_patterns(patterns('snippets.views',
url(r'^users/(?P&lt;pk&gt;[0-9]+)/$', url(r'^users/(?P&lt;pk&gt;[0-9]+)/$',
views.UserDetail.as_view(), views.UserDetail.as_view(),
name='user-detail') name='user-detail')
)) ])
# Login and logout views for the browsable API # Login and logout views for the browsable API
urlpatterns += patterns('', urlpatterns += [
url(r'^api-auth/', include('rest_framework.urls', url(r'^api-auth/', include('rest_framework.urls',
namespace='rest_framework')), namespace='rest_framework')),
) ]
</code></pre> </code></pre>
<h2 id="adding-pagination">Adding pagination</h2> <h2 id="adding-pagination">Adding pagination</h2>
<p>The list views for users and code snippets could end up returning quite a lot of instances, so really we'd like to make sure we paginate the results, and allow the API client to step through each of the individual pages.</p> <p>The list views for users and code snippets could end up returning quite a lot of instances, so really we'd like to make sure we paginate the results, and allow the API client to step through each of the individual pages.</p>
......
...@@ -275,19 +275,19 @@ user_detail = UserViewSet.as_view({ ...@@ -275,19 +275,19 @@ user_detail = UserViewSet.as_view({
</code></pre> </code></pre>
<p>Notice how we're creating multiple views from each <code>ViewSet</code> class, by binding the http methods to the required action for each view.</p> <p>Notice how we're creating multiple views from each <code>ViewSet</code> class, by binding the http methods to the required action for each view.</p>
<p>Now that we've bound our resources into concrete views, we can register the views with the URL conf as usual.</p> <p>Now that we've bound our resources into concrete views, we can register the views with the URL conf as usual.</p>
<pre class="prettyprint lang-py"><code>urlpatterns = format_suffix_patterns(patterns('snippets.views', <pre class="prettyprint lang-py"><code>urlpatterns = format_suffix_patterns([
url(r'^$', 'api_root'), url(r'^$', api_root),
url(r'^snippets/$', snippet_list, name='snippet-list'), url(r'^snippets/$', snippet_list, name='snippet-list'),
url(r'^snippets/(?P&lt;pk&gt;[0-9]+)/$', snippet_detail, name='snippet-detail'), 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'^snippets/(?P&lt;pk&gt;[0-9]+)/highlight/$', snippet_highlight, name='snippet-highlight'),
url(r'^users/$', user_list, name='user-list'), url(r'^users/$', user_list, name='user-list'),
url(r'^users/(?P&lt;pk&gt;[0-9]+)/$', user_detail, name='user-detail') url(r'^users/(?P&lt;pk&gt;[0-9]+)/$', user_detail, name='user-detail')
)) ])
</code></pre> </code></pre>
<h2 id="using-routers">Using Routers</h2> <h2 id="using-routers">Using Routers</h2>
<p>Because we're using <code>ViewSet</code> classes rather than <code>View</code> classes, we actually don't need to design the URL conf ourselves. The conventions for wiring up resources into views and urls can be handled automatically, using a <code>Router</code> class. All we need to do is register the appropriate view sets with a router, and let it do the rest.</p> <p>Because we're using <code>ViewSet</code> classes rather than <code>View</code> classes, we actually don't need to design the URL conf ourselves. The conventions for wiring up resources into views and urls can be handled automatically, using a <code>Router</code> class. All we need to do is register the appropriate view sets with a router, and let it do the rest.</p>
<p>Here's our re-wired <code>urls.py</code> file.</p> <p>Here's our re-wired <code>urls.py</code> file.</p>
<pre class="prettyprint lang-py"><code>from django.conf.urls import patterns, url, include <pre class="prettyprint lang-py"><code>from django.conf.urls import url, include
from snippets import views from snippets import views
from rest_framework.routers import DefaultRouter from rest_framework.routers import DefaultRouter
...@@ -298,10 +298,10 @@ router.register(r'users', views.UserViewSet) ...@@ -298,10 +298,10 @@ router.register(r'users', views.UserViewSet)
# The API URLs are now determined automatically by the router. # The API URLs are now determined automatically by the router.
# Additionally, we include the login URLs for the browseable API. # Additionally, we include the login URLs for the browseable API.
urlpatterns = patterns('', urlpatterns = [
url(r'^', include(router.urls)), url(r'^', include(router.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')) url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
) ]
</code></pre> </code></pre>
<p>Registering the viewsets with the router is similar to providing a urlpattern. We include two arguments - the URL prefix for the views, and the viewset itself.</p> <p>Registering the viewsets with the router is similar to providing a urlpattern. We include two arguments - the URL prefix for the views, and the viewset itself.</p>
<p>The <code>DefaultRouter</code> class we're using also automatically creates the API root view for us, so we can now delete the <code>api_root</code> method from our <code>views</code> module.</p> <p>The <code>DefaultRouter</code> class we're using also automatically creates the API root view for us, so we can now delete the <code>api_root</code> method from our <code>views</code> module.</p>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment