Deployed 761f56ef with MkDocs version: 1.1

This commit is contained in:
Tom Christie 2021-09-10 13:45:21 +00:00
parent 0ecbb711c5
commit dee977cf98
20 changed files with 134 additions and 214 deletions

View File

@ -538,13 +538,13 @@
<p>&mdash; Jacob Kaplan-Moss, <a href="https://jacobian.org/writing/rest-worst-practices/">"REST worst practices"</a></p> <p>&mdash; Jacob Kaplan-Moss, <a href="https://jacobian.org/writing/rest-worst-practices/">"REST worst practices"</a></p>
</blockquote> </blockquote>
<p>Authentication is the mechanism of associating an incoming request with a set of identifying credentials, such as the user the request came from, or the token that it was signed with. The <a href="../permissions/">permission</a> and <a href="../throttling/">throttling</a> policies can then use those credentials to determine if the request should be permitted.</p> <p>Authentication is the mechanism of associating an incoming request with a set of identifying credentials, such as the user the request came from, or the token that it was signed with. The <a href="../permissions/">permission</a> and <a href="../throttling/">throttling</a> policies can then use those credentials to determine if the request should be permitted.</p>
<p>REST framework provides a number of authentication schemes out of the box, and also allows you to implement custom schemes.</p> <p>REST framework provides several authentication schemes out of the box, and also allows you to implement custom schemes.</p>
<p>Authentication is always run at the very start of the view, before the permission and throttling checks occur, and before any other code is allowed to proceed.</p> <p>Authentication always runs at the very start of the view, before the permission and throttling checks occur, and before any other code is allowed to proceed.</p>
<p>The <code>request.user</code> property will typically be set to an instance of the <code>contrib.auth</code> package's <code>User</code> class.</p> <p>The <code>request.user</code> property will typically be set to an instance of the <code>contrib.auth</code> package's <code>User</code> class.</p>
<p>The <code>request.auth</code> property is used for any additional authentication information, for example, it may be used to represent an authentication token that the request was signed with.</p> <p>The <code>request.auth</code> property is used for any additional authentication information, for example, it may be used to represent an authentication token that the request was signed with.</p>
<hr /> <hr />
<p><strong>Note:</strong> Don't forget that <strong>authentication by itself won't allow or disallow an incoming request</strong>, it simply identifies the credentials that the request was made with.</p> <p><strong>Note:</strong> Don't forget that <strong>authentication by itself won't allow or disallow an incoming request</strong>, it simply identifies the credentials that the request was made with.</p>
<p>For information on how to setup the permission polices for your API please see the <a href="../permissions/">permissions documentation</a>.</p> <p>For information on how to set up the permission policies for your API please see the <a href="../permissions/">permissions documentation</a>.</p>
<hr /> <hr />
<h2 id="how-authentication-is-determined"><a class="toclink" href="#how-authentication-is-determined">How authentication is determined</a></h2> <h2 id="how-authentication-is-determined"><a class="toclink" href="#how-authentication-is-determined">How authentication is determined</a></h2>
<p>The authentication schemes are always defined as a list of classes. REST framework will attempt to authenticate with each class in the list, and will set <code>request.user</code> and <code>request.auth</code> using the return value of the first class that successfully authenticates.</p> <p>The authentication schemes are always defined as a list of classes. REST framework will attempt to authenticate with each class in the list, and will set <code>request.user</code> and <code>request.auth</code> using the return value of the first class that successfully authenticates.</p>
@ -673,7 +673,7 @@ for user in User.objects.all():
Token.objects.get_or_create(user=user) Token.objects.get_or_create(user=user)
</code></pre> </code></pre>
<h5 id="by-exposing-an-api-endpoint"><a class="toclink" href="#by-exposing-an-api-endpoint">By exposing an api endpoint</a></h5> <h5 id="by-exposing-an-api-endpoint"><a class="toclink" href="#by-exposing-an-api-endpoint">By exposing an api endpoint</a></h5>
<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 behaviour. To use it, add the <code>obtain_auth_token</code> view to your URLconf:</p>
<pre><code>from rest_framework.authtoken import views <pre><code>from rest_framework.authtoken import views
urlpatterns += [ urlpatterns += [
path('api-token-auth/', views.obtain_auth_token) path('api-token-auth/', views.obtain_auth_token)
@ -684,7 +684,7 @@ urlpatterns += [
<pre><code>{ 'token' : '9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b' } <pre><code>{ 'token' : '9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b' }
</code></pre> </code></pre>
<p>Note that the default <code>obtain_auth_token</code> view explicitly uses JSON requests and responses, rather than using default renderer and parser classes in your settings.</p> <p>Note that the default <code>obtain_auth_token</code> view explicitly uses JSON requests and responses, rather than using default renderer and parser classes in your settings.</p>
<p>By default there are no permissions or throttling applied to the <code>obtain_auth_token</code> view. If you do wish to apply throttling you'll need to override the view class, <p>By default, there are no permissions or throttling applied to the <code>obtain_auth_token</code> view. If you do wish to apply to throttle you'll need to override the view class,
and include them using the <code>throttle_classes</code> attribute.</p> and include them using the <code>throttle_classes</code> attribute.</p>
<p>If you need a customized version of the <code>obtain_auth_token</code> view, you can do so by subclassing the <code>ObtainAuthToken</code> view class, and using that in your url conf instead.</p> <p>If you need a customized version of the <code>obtain_auth_token</code> view, you can do so by subclassing the <code>ObtainAuthToken</code> view class, and using that in your url conf instead.</p>
<p>For example, you may return additional user information beyond the <code>token</code> value:</p> <p>For example, you may return additional user information beyond the <code>token</code> value:</p>
@ -712,7 +712,7 @@ class CustomAuthToken(ObtainAuthToken):
] ]
</code></pre> </code></pre>
<h5 id="with-django-admin"><a class="toclink" href="#with-django-admin">With Django admin</a></h5> <h5 id="with-django-admin"><a class="toclink" href="#with-django-admin">With Django admin</a></h5>
<p>It is also possible to create Tokens manually through admin interface. In case you are using a large user base, we recommend that you monkey patch the <code>TokenAdmin</code> class to customize it to your needs, more specifically by declaring the <code>user</code> field as <code>raw_field</code>.</p> <p>It is also possible to create Tokens manually through the admin interface. In case you are using a large user base, we recommend that you monkey patch the <code>TokenAdmin</code> class customize it to your needs, more specifically by declaring the <code>user</code> field as <code>raw_field</code>.</p>
<p><code>your_app/admin.py</code>:</p> <p><code>your_app/admin.py</code>:</p>
<pre><code>from rest_framework.authtoken.admin import TokenAdmin <pre><code>from rest_framework.authtoken.admin import TokenAdmin
@ -736,9 +736,9 @@ TokenAdmin.raw_id_fields = ['user']
<li><code>request.auth</code> will be <code>None</code>.</li> <li><code>request.auth</code> will be <code>None</code>.</li>
</ul> </ul>
<p>Unauthenticated responses that are denied permission will result in an <code>HTTP 403 Forbidden</code> response.</p> <p>Unauthenticated responses that are denied permission will result in an <code>HTTP 403 Forbidden</code> response.</p>
<p>If you're using an AJAX style API with SessionAuthentication, you'll need to make sure you include a valid CSRF token for any "unsafe" HTTP method calls, such as <code>PUT</code>, <code>PATCH</code>, <code>POST</code> or <code>DELETE</code> requests. See the <a href="https://docs.djangoproject.com/en/stable/ref/csrf/#ajax">Django CSRF documentation</a> for more details.</p> <p>If you're using an AJAX-style API with SessionAuthentication, you'll need to make sure you include a valid CSRF token for any "unsafe" HTTP method calls, such as <code>PUT</code>, <code>PATCH</code>, <code>POST</code> or <code>DELETE</code> requests. See the <a href="https://docs.djangoproject.com/en/stable/ref/csrf/#ajax">Django CSRF documentation</a> for more details.</p>
<p><strong>Warning</strong>: Always use Django's standard login view when creating login pages. This will ensure your login views are properly protected.</p> <p><strong>Warning</strong>: Always use Django's standard login view when creating login pages. This will ensure your login views are properly protected.</p>
<p>CSRF validation in REST framework works slightly differently to standard Django due to the need to support both session and non-session based authentication to the same views. This means that only authenticated requests require CSRF tokens, and anonymous requests may be sent without CSRF tokens. This behaviour is not suitable for login views, which should always have CSRF validation applied.</p> <p>CSRF validation in REST framework works slightly differently from standard Django due to the need to support both session and non-session based authentication to the same views. This means that only authenticated requests require CSRF tokens, and anonymous requests may be sent without CSRF tokens. This behaviour is not suitable for login views, which should always have CSRF validation applied.</p>
<h2 id="remoteuserauthentication"><a class="toclink" href="#remoteuserauthentication">RemoteUserAuthentication</a></h2> <h2 id="remoteuserauthentication"><a class="toclink" href="#remoteuserauthentication">RemoteUserAuthentication</a></h2>
<p>This authentication scheme allows you to delegate authentication to your web server, which sets the <code>REMOTE_USER</code> <p>This authentication scheme allows you to delegate authentication to your web server, which sets the <code>REMOTE_USER</code>
environment variable.</p> environment variable.</p>
@ -762,7 +762,7 @@ already exist. To change this and other behaviour, consult the
<p>Typically the approach you should take is:</p> <p>Typically the approach you should take is:</p>
<ul> <ul>
<li>If authentication is not attempted, return <code>None</code>. Any other authentication schemes also in use will still be checked.</li> <li>If authentication is not attempted, return <code>None</code>. Any other authentication schemes also in use will still be checked.</li>
<li>If authentication is attempted but fails, raise a <code>AuthenticationFailed</code> exception. An error response will be returned immediately, regardless of any permissions checks, and without checking any other authentication schemes.</li> <li>If authentication is attempted but fails, raise an <code>AuthenticationFailed</code> exception. An error response will be returned immediately, regardless of any permissions checks, and without checking any other authentication schemes.</li>
</ul> </ul>
<p>You <em>may</em> also override the <code>.authenticate_header(self, request)</code> method. If implemented, it should return a string that will be used as the value of the <code>WWW-Authenticate</code> header in a <code>HTTP 401 Unauthorized</code> response.</p> <p>You <em>may</em> also override the <code>.authenticate_header(self, request)</code> method. If implemented, it should return a string that will be used as the value of the <code>WWW-Authenticate</code> header in a <code>HTTP 401 Unauthorized</code> response.</p>
<p>If the <code>.authenticate_header()</code> method is not overridden, the authentication scheme will return <code>HTTP 403 Forbidden</code> responses when an unauthenticated request is denied access.</p> <p>If the <code>.authenticate_header()</code> method is not overridden, the authentication scheme will return <code>HTTP 403 Forbidden</code> responses when an unauthenticated request is denied access.</p>
@ -790,7 +790,7 @@ class ExampleAuthentication(authentication.BaseAuthentication):
</code></pre> </code></pre>
<hr /> <hr />
<h1 id="third-party-packages"><a class="toclink" href="#third-party-packages">Third party packages</a></h1> <h1 id="third-party-packages"><a class="toclink" href="#third-party-packages">Third party packages</a></h1>
<p>The following third party packages are also available.</p> <p>The following third-party packages are also available.</p>
<h2 id="django-oauth-toolkit"><a class="toclink" href="#django-oauth-toolkit">Django OAuth Toolkit</a></h2> <h2 id="django-oauth-toolkit"><a class="toclink" href="#django-oauth-toolkit">Django OAuth Toolkit</a></h2>
<p>The <a href="https://github.com/evonove/django-oauth-toolkit">Django OAuth Toolkit</a> package provides OAuth 2.0 support and works with Python 3.4+. The package is maintained by <a href="https://github.com/jazzband/">jazzband</a> and uses the excellent <a href="https://github.com/idan/oauthlib">OAuthLib</a>. The package is well documented, and well supported and is currently our <strong>recommended package for OAuth 2.0 support</strong>.</p> <p>The <a href="https://github.com/evonove/django-oauth-toolkit">Django OAuth Toolkit</a> package provides OAuth 2.0 support and works with Python 3.4+. The package is maintained by <a href="https://github.com/jazzband/">jazzband</a> and uses the excellent <a href="https://github.com/idan/oauthlib">OAuthLib</a>. The package is well documented, and well supported and is currently our <strong>recommended package for OAuth 2.0 support</strong>.</p>
<h4 id="installation-configuration"><a class="toclink" href="#installation-configuration">Installation &amp; configuration</a></h4> <h4 id="installation-configuration"><a class="toclink" href="#installation-configuration">Installation &amp; configuration</a></h4>
@ -812,7 +812,7 @@ REST_FRAMEWORK = {
<p>For more details see the <a href="https://django-oauth-toolkit.readthedocs.io/en/latest/rest-framework/getting_started.html">Django REST framework - Getting started</a> documentation.</p> <p>For more details see the <a href="https://django-oauth-toolkit.readthedocs.io/en/latest/rest-framework/getting_started.html">Django REST framework - Getting started</a> documentation.</p>
<h2 id="django-rest-framework-oauth"><a class="toclink" href="#django-rest-framework-oauth">Django REST framework OAuth</a></h2> <h2 id="django-rest-framework-oauth"><a class="toclink" href="#django-rest-framework-oauth">Django REST framework OAuth</a></h2>
<p>The <a href="https://jpadilla.github.io/django-rest-framework-oauth/">Django REST framework OAuth</a> package provides both OAuth1 and OAuth2 support for REST framework.</p> <p>The <a href="https://jpadilla.github.io/django-rest-framework-oauth/">Django REST framework OAuth</a> package provides both OAuth1 and OAuth2 support for REST framework.</p>
<p>This package was previously included directly in REST framework but is now supported and maintained as a third party package.</p> <p>This package was previously included directly in the REST framework but is now supported and maintained as a third-party package.</p>
<h4 id="installation-configuration_1"><a class="toclink" href="#installation-configuration_1">Installation &amp; configuration</a></h4> <h4 id="installation-configuration_1"><a class="toclink" href="#installation-configuration_1">Installation &amp; configuration</a></h4>
<p>Install the package using <code>pip</code>.</p> <p>Install the package using <code>pip</code>.</p>
<pre><code>pip install djangorestframework-oauth <pre><code>pip install djangorestframework-oauth
@ -825,7 +825,7 @@ REST_FRAMEWORK = {
<h2 id="http-signature-authentication"><a class="toclink" href="#http-signature-authentication">HTTP Signature Authentication</a></h2> <h2 id="http-signature-authentication"><a class="toclink" href="#http-signature-authentication">HTTP Signature Authentication</a></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="https://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> (outdated) package which provides an easy to use HTTP Signature Authentication mechanism. You can use the updated fork version of <a href="https://github.com/etoccalino/django-rest-framework-httpsignature">djangorestframework-httpsignature</a>, which is <a href="https://github.com/ahknight/drf-httpsig">drf-httpsig</a>.</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="https://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> (outdated) package which provides an easy to use HTTP Signature Authentication mechanism. You can use the updated fork version of <a href="https://github.com/etoccalino/django-rest-framework-httpsignature">djangorestframework-httpsignature</a>, which is <a href="https://github.com/ahknight/drf-httpsig">drf-httpsig</a>.</p>
<h2 id="djoser"><a class="toclink" href="#djoser">Djoser</a></h2> <h2 id="djoser"><a class="toclink" href="#djoser">Djoser</a></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> <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 uses token-based authentication. This is ready to use REST implementation of the Django authentication system.</p>
<h2 id="django-rest-auth-dj-rest-auth"><a class="toclink" href="#django-rest-auth-dj-rest-auth">django-rest-auth / dj-rest-auth</a></h2> <h2 id="django-rest-auth-dj-rest-auth"><a class="toclink" href="#django-rest-auth-dj-rest-auth">django-rest-auth / dj-rest-auth</a></h2>
<p>This library provides a set of REST API endpoints for registration, authentication (including social media authentication), password reset, retrieve and update user details, etc. By having these API endpoints, your client apps such as AngularJS, iOS, Android, and others can communicate to your Django backend site independently via REST APIs for user management.</p> <p>This library provides a set of REST API endpoints for registration, authentication (including social media authentication), password reset, retrieve and update user details, etc. By having these API endpoints, your client apps such as AngularJS, iOS, Android, and others can communicate to your Django backend site independently via REST APIs for user management.</p>
<p>There are currently two forks of this project.</p> <p>There are currently two forks of this project.</p>
@ -836,11 +836,11 @@ REST_FRAMEWORK = {
<h2 id="django-rest-framework-social-oauth2"><a class="toclink" href="#django-rest-framework-social-oauth2">django-rest-framework-social-oauth2</a></h2> <h2 id="django-rest-framework-social-oauth2"><a class="toclink" href="#django-rest-framework-social-oauth2">django-rest-framework-social-oauth2</a></h2>
<p><a href="https://github.com/PhilipGarnero/django-rest-framework-social-oauth2">Django-rest-framework-social-oauth2</a> library provides an easy way to integrate social plugins (facebook, twitter, google, etc.) to your authentication system and an easy oauth2 setup. With this library, you will be able to authenticate users based on external tokens (e.g. facebook access token), convert these tokens to "in-house" oauth2 tokens and use and generate oauth2 tokens to authenticate your users.</p> <p><a href="https://github.com/PhilipGarnero/django-rest-framework-social-oauth2">Django-rest-framework-social-oauth2</a> library provides an easy way to integrate social plugins (facebook, twitter, google, etc.) to your authentication system and an easy oauth2 setup. With this library, you will be able to authenticate users based on external tokens (e.g. facebook access token), convert these tokens to "in-house" oauth2 tokens and use and generate oauth2 tokens to authenticate your users.</p>
<h2 id="django-rest-knox"><a class="toclink" href="#django-rest-knox">django-rest-knox</a></h2> <h2 id="django-rest-knox"><a class="toclink" href="#django-rest-knox">django-rest-knox</a></h2>
<p><a href="https://github.com/James1345/django-rest-knox">Django-rest-knox</a> library provides models and views to handle token based authentication in a more secure and extensible way than the built-in TokenAuthentication scheme - with Single Page Applications and Mobile clients in mind. It provides per-client tokens, and views to generate them when provided some other authentication (usually basic authentication), to delete the token (providing a server enforced logout) and to delete all tokens (logs out all clients that a user is logged into).</p> <p><a href="https://github.com/James1345/django-rest-knox">Django-rest-knox</a> library provides models and views to handle token-based authentication in a more secure and extensible way than the built-in TokenAuthentication scheme - with Single Page Applications and Mobile clients in mind. It provides per-client tokens, and views to generate them when provided some other authentication (usually basic authentication), to delete the token (providing a server enforced logout) and to delete all tokens (logs out all clients that a user is logged into).</p>
<h2 id="drfpasswordless"><a class="toclink" href="#drfpasswordless">drfpasswordless</a></h2> <h2 id="drfpasswordless"><a class="toclink" href="#drfpasswordless">drfpasswordless</a></h2>
<p><a href="https://github.com/aaronn/django-rest-framework-passwordless">drfpasswordless</a> adds (Medium, Square Cash inspired) passwordless support to Django REST Framework's own TokenAuthentication scheme. Users log in and sign up with a token sent to a contact point like an email address or a mobile number.</p> <p><a href="https://github.com/aaronn/django-rest-framework-passwordless">drfpasswordless</a> adds (Medium, Square Cash inspired) passwordless support to Django REST Framework's TokenAuthentication scheme. Users log in and sign up with a token sent to a contact point like an email address or a mobile number.</p>
<h2 id="django-rest-authemail"><a class="toclink" href="#django-rest-authemail">django-rest-authemail</a></h2> <h2 id="django-rest-authemail"><a class="toclink" href="#django-rest-authemail">django-rest-authemail</a></h2>
<p><a href="https://github.com/celiao/django-rest-authemail">django-rest-authemail</a> provides a RESTful API interface for user signup and authentication. Email addresses are used for authentication, rather than usernames. API endpoints are available for signup, signup email verification, login, logout, password reset, password reset verification, email change, email change verification, password change, and user detail. A fully-functional example project and detailed instructions are included.</p> <p><a href="https://github.com/celiao/django-rest-authemail">django-rest-authemail</a> provides a RESTful API interface for user signup and authentication. Email addresses are used for authentication, rather than usernames. API endpoints are available for signup, signup email verification, login, logout, password reset, password reset verification, email change, email change verification, password change, and user detail. A fully functional example project and detailed instructions are included.</p>
<h2 id="django-rest-durin"><a class="toclink" href="#django-rest-durin">Django-Rest-Durin</a></h2> <h2 id="django-rest-durin"><a class="toclink" href="#django-rest-durin">Django-Rest-Durin</a></h2>
<p><a href="https://github.com/eshaan7/django-rest-durin">Django-Rest-Durin</a> is built with the idea to have one library that does token auth for multiple Web/CLI/Mobile API clients via one interface but allows different token configuration for each API Client that consumes the API. It provides support for multiple tokens per user via custom models, views, permissions that work with Django-Rest-Framework. The token expiration time can be different per API client and is customizable via the Django Admin Interface.</p> <p><a href="https://github.com/eshaan7/django-rest-durin">Django-Rest-Durin</a> is built with the idea to have one library that does token auth for multiple Web/CLI/Mobile API clients via one interface but allows different token configuration for each API Client that consumes the API. It provides support for multiple tokens per user via custom models, views, permissions that work with Django-Rest-Framework. The token expiration time can be different per API client and is customizable via the Django Admin Interface.</p>
<p>More information can be found in the <a href="https://django-rest-durin.readthedocs.io/en/latest/index.html">Documentation</a>.</p> <p>More information can be found in the <a href="https://django-rest-durin.readthedocs.io/en/latest/index.html">Documentation</a>.</p>

View File

@ -472,7 +472,7 @@
</li> </li>
<li> <li>
<a href="#pagination-schemas">Pagination &amp; schemas</a> <a href="#filtering-schemas">Filtering &amp; schemas</a>
</li> </li>
@ -767,7 +767,7 @@ class CustomSearchFilter(filters.SearchFilter):
<p>Generic filters may also present an interface in the browsable API. To do so you should implement a <code>to_html()</code> method which returns a rendered HTML representation of the filter. This method should have the following signature:</p> <p>Generic filters may also present an interface in the browsable API. To do so you should implement a <code>to_html()</code> method which returns a rendered HTML representation of the filter. This method should have the following signature:</p>
<p><code>to_html(self, request, queryset, view)</code></p> <p><code>to_html(self, request, queryset, view)</code></p>
<p>The method should return a rendered HTML string.</p> <p>The method should return a rendered HTML string.</p>
<h2 id="pagination-schemas"><a class="toclink" href="#pagination-schemas">Pagination &amp; schemas</a></h2> <h2 id="filtering-schemas"><a class="toclink" href="#filtering-schemas">Filtering &amp; schemas</a></h2>
<p>You can also make the filter controls available to the schema autogeneration <p>You can also make the filter controls available to the schema autogeneration
that REST framework provides, by implementing a <code>get_schema_fields()</code> method. This method should have the following signature:</p> that REST framework provides, by implementing a <code>get_schema_fields()</code> method. This method should have the following signature:</p>
<p><code>get_schema_fields(self, view)</code></p> <p><code>get_schema_fields(self, view)</code></p>

View File

@ -666,10 +666,10 @@ class StandardResultsSetPagination(PageNumberPagination):
</ul> </ul>
<hr /> <hr />
<h1 id="custom-pagination-styles"><a class="toclink" href="#custom-pagination-styles">Custom pagination styles</a></h1> <h1 id="custom-pagination-styles"><a class="toclink" href="#custom-pagination-styles">Custom pagination styles</a></h1>
<p>To create a custom pagination serializer class you should subclass <code>pagination.BasePagination</code> and override the <code>paginate_queryset(self, queryset, request, view=None)</code> and <code>get_paginated_response(self, data)</code> methods:</p> <p>To create a custom pagination serializer class, you should inherit the subclass <code>pagination.BasePagination</code>, override the <code>paginate_queryset(self, queryset, request, view=None)</code>, and <code>get_paginated_response(self, data)</code> methods:</p>
<ul> <ul>
<li>The <code>paginate_queryset</code> method is passed the initial queryset and should return an iterable object that contains only the data in the requested page.</li> <li>The <code>paginate_queryset</code> method is passed to the initial queryset and should return an iterable object. That object contains only the data in the requested page.</li>
<li>The <code>get_paginated_response</code> method is passed the serialized page data and should return a <code>Response</code> instance.</li> <li>The <code>get_paginated_response</code> method is passed to the serialized page data and should return a <code>Response</code> instance.</li>
</ul> </ul>
<p>Note that the <code>paginate_queryset</code> method may set state on the pagination instance, that may later be used by the <code>get_paginated_response</code> method.</p> <p>Note that the <code>paginate_queryset</code> method may set state on the pagination instance, that may later be used by the <code>get_paginated_response</code> method.</p>
<h2 id="example"><a class="toclink" href="#example">Example</a></h2> <h2 id="example"><a class="toclink" href="#example">Example</a></h2>

View File

@ -573,7 +573,7 @@
<h1 id="renderers"><a class="toclink" href="#renderers">Renderers</a></h1> <h1 id="renderers"><a class="toclink" href="#renderers">Renderers</a></h1>
<blockquote> <blockquote>
<p>Before a TemplateResponse instance can be returned to the client, it must be rendered. The rendering process takes the intermediate representation of template and context, and turns it into the final byte stream that can be served to the client.</p> <p>Before a TemplateResponse instance can be returned to the client, it must be rendered. The rendering process takes the intermediate representation of template and context, and turns it into the final byte stream that can be served to the client.</p>
<p>&mdash; <a href="https://docs.djangoproject.com/en/stable/stable/template-response/#the-rendering-process">Django documentation</a></p> <p>&mdash; <a href="https://docs.djangoproject.com/en/stable/ref/template-response/#the-rendering-process">Django documentation</a></p>
</blockquote> </blockquote>
<p>REST framework includes a number of built in Renderer classes, that allow you to return responses with various media types. There is also support for defining your own custom renderers, which gives you the flexibility to design your own media types.</p> <p>REST framework includes a number of built in Renderer classes, that allow you to return responses with various media types. There is also support for defining your own custom renderers, which gives you the flexibility to design your own media types.</p>
<h2 id="how-the-renderer-is-determined"><a class="toclink" href="#how-the-renderer-is-determined">How the renderer is determined</a></h2> <h2 id="how-the-renderer-is-determined"><a class="toclink" href="#how-the-renderer-is-determined">How the renderer is determined</a></h2>
@ -644,7 +644,7 @@ def user_count_view(request, format=None):
Unlike other renderers, the data passed to the <code>Response</code> does not need to be serialized. Also, unlike other renderers, you may want to include a <code>template_name</code> argument when creating the <code>Response</code>.</p> Unlike other renderers, the data passed to the <code>Response</code> does not need to be serialized. Also, unlike other renderers, you may want to include a <code>template_name</code> argument when creating the <code>Response</code>.</p>
<p>The TemplateHTMLRenderer will create a <code>RequestContext</code>, using the <code>response.data</code> as the context dict, and determine a template name to use to render the context.</p> <p>The TemplateHTMLRenderer will create a <code>RequestContext</code>, using the <code>response.data</code> as the context dict, and determine a template name to use to render the context.</p>
<hr /> <hr />
<p><strong>Note:</strong> When used with a view that makes use of a serializer the <code>Response</code> sent for rendering may not be a dictionay and will need to be wrapped in a dict before returning to allow the TemplateHTMLRenderer to render it. For example:</p> <p><strong>Note:</strong> When used with a view that makes use of a serializer the <code>Response</code> sent for rendering may not be a dictionary and will need to be wrapped in a dict before returning to allow the TemplateHTMLRenderer to render it. For example:</p>
<pre><code>response.data = {'results': response.data} <pre><code>response.data = {'results': response.data}
</code></pre> </code></pre>
<hr /> <hr />

View File

@ -449,7 +449,7 @@
<h1 id="schema"><a class="toclink" href="#schema">Schema</a></h1> <h1 id="schema"><a class="toclink" href="#schema">Schema</a></h1>
<blockquote> <blockquote>
<p>A machine-readable [schema] describes what resources are available via the API, what their URLs are, how they are represented and what operations they support.</p> <p>A machine-readable [schema] describes what resources are available via the API, what their URLs are, how they are represented and what operations they support.</p>
<p>&mdash; Heroku, [JSON Schema for the Heroku Platform API][cite]</p> <p>&mdash; Heroku, <a href="https://blog.heroku.com/archives/2014/1/8/json_schema_for_heroku_platform_api">JSON Schema for the Heroku Platform API</a></p>
</blockquote> </blockquote>
<p>API schemas are a useful tool that allow for a range of use cases, including <p>API schemas are a useful tool that allow for a range of use cases, including
generating reference documentation, or driving dynamic client libraries that generating reference documentation, or driving dynamic client libraries that
@ -738,6 +738,14 @@ view name. The operationId looks like "listItems", "retrieveItem",
operationIds.</p> operationIds.</p>
<p>In order to work around this, you can override <code>get_operation_id_base()</code> to <p>In order to work around this, you can override <code>get_operation_id_base()</code> to
provide a different base for name part of the ID.</p> provide a different base for name part of the ID.</p>
<h4 id="get_serializer"><a class="toclink" href="#get_serializer"><code>get_serializer()</code></a></h4>
<p>If the view has implemented <code>get_serializer()</code>, returns the result.</p>
<h4 id="get_request_serializer"><a class="toclink" href="#get_request_serializer"><code>get_request_serializer()</code></a></h4>
<p>By default returns <code>get_serializer()</code> but can be overridden to
differentiate between request and response objects.</p>
<h4 id="get_response_serializer"><a class="toclink" href="#get_response_serializer"><code>get_response_serializer()</code></a></h4>
<p>By default returns <code>get_serializer()</code> but can be overridden to
differentiate between request and response objects.</p>
<h3 id="autoschema__init__-kwargs"><a class="toclink" href="#autoschema__init__-kwargs"><code>AutoSchema.__init__()</code> kwargs</a></h3> <h3 id="autoschema__init__-kwargs"><a class="toclink" href="#autoschema__init__-kwargs"><code>AutoSchema.__init__()</code> kwargs</a></h3>
<p><code>AutoSchema</code> provides a number of <code>__init__()</code> kwargs that can be used for <p><code>AutoSchema</code> provides a number of <code>__init__()</code> kwargs that can be used for
common customizations, if the default generated values are not appropriate.</p> common customizations, if the default generated values are not appropriate.</p>

View File

@ -1109,10 +1109,10 @@ AccountSerializer():
<p>This property should be the serializer field class, that is used for relational fields by default.</p> <p>This property should be the serializer field class, that is used for relational fields by default.</p>
<p>For <code>ModelSerializer</code> this defaults to <code>PrimaryKeyRelatedField</code>.</p> <p>For <code>ModelSerializer</code> this defaults to <code>PrimaryKeyRelatedField</code>.</p>
<p>For <code>HyperlinkedModelSerializer</code> this defaults to <code>serializers.HyperlinkedRelatedField</code>.</p> <p>For <code>HyperlinkedModelSerializer</code> this defaults to <code>serializers.HyperlinkedRelatedField</code>.</p>
<h3 id="serializer_url_field"><a class="toclink" href="#serializer_url_field"><code>serializer_url_field</code></a></h3> <h3 id="serializer_url_field"><a class="toclink" href="#serializer_url_field"><code>.serializer_url_field</code></a></h3>
<p>The serializer field class that should be used for any <code>url</code> field on the serializer.</p> <p>The serializer field class that should be used for any <code>url</code> field on the serializer.</p>
<p>Defaults to <code>serializers.HyperlinkedIdentityField</code></p> <p>Defaults to <code>serializers.HyperlinkedIdentityField</code></p>
<h3 id="serializer_choice_field"><a class="toclink" href="#serializer_choice_field"><code>serializer_choice_field</code></a></h3> <h3 id="serializer_choice_field"><a class="toclink" href="#serializer_choice_field"><code>.serializer_choice_field</code></a></h3>
<p>The serializer field class that should be used for any choice fields on the serializer.</p> <p>The serializer field class that should be used for any choice fields on the serializer.</p>
<p>Defaults to <code>serializers.ChoiceField</code></p> <p>Defaults to <code>serializers.ChoiceField</code></p>
<h3 id="the-field_class-and-field_kwargs-api"><a class="toclink" href="#the-field_class-and-field_kwargs-api">The field_class and field_kwargs API</a></h3> <h3 id="the-field_class-and-field_kwargs-api"><a class="toclink" href="#the-field_class-and-field_kwargs-api">The field_class and field_kwargs API</a></h3>

View File

@ -681,7 +681,7 @@ an attribute on the serializer, having initially been passed using
<p>In the case of update operations on <em>nested</em> serializers there's no way of <p>In the case of update operations on <em>nested</em> serializers there's no way of
applying this exclusion, because the instance is not available.</p> applying this exclusion, because the instance is not available.</p>
<p>Again, you'll probably want to explicitly remove the validator from the <p>Again, you'll probably want to explicitly remove the validator from the
serializer class, and write the code the for the validation constraint serializer class, and write the code for the validation constraint
explicitly, in a <code>.validate()</code> method, or in the view.</p> explicitly, in a <code>.validate()</code> method, or in the view.</p>
<h2 id="debugging-complex-cases"><a class="toclink" href="#debugging-complex-cases">Debugging complex cases</a></h2> <h2 id="debugging-complex-cases"><a class="toclink" href="#debugging-complex-cases">Debugging complex cases</a></h2>
<p>If you're not sure exactly what behavior a <code>ModelSerializer</code> class will <p>If you're not sure exactly what behavior a <code>ModelSerializer</code> class will

View File

@ -517,10 +517,17 @@
<a href="https://github.com/encode/django-rest-framework">Django REST Framework repo</a> on GitHub.</p> <a href="https://github.com/encode/django-rest-framework">Django REST Framework repo</a> on GitHub.</p>
<p>Then clone your fork. The clone command will look like this, with your GitHub <p>Then clone your fork. The clone command will look like this, with your GitHub
username instead of YOUR-USERNAME:</p> username instead of YOUR-USERNAME:</p>
<pre><code>git clone https://github.com/YOUR-USERNAME/Spoon-Knife <pre><code>git clone https://github.com/YOUR-USERNAME/django-rest-framework
</code></pre> </code></pre>
<p>See GitHub's <a href="https://help.github.com/articles/fork-a-repo/"><em>Fork a Repo</em></a> Guide for more help.</p> <p>See GitHub's <a href="https://help.github.com/articles/fork-a-repo/"><em>Fork a Repo</em></a> Guide for more help.</p>
<p>Changes should broadly follow the <a href="https://www.python.org/dev/peps/pep-0008/">PEP 8</a> style conventions, and we recommend you set up your editor to automatically indicate non-conforming styles.</p> <p>Changes should broadly follow the <a href="https://www.python.org/dev/peps/pep-0008/">PEP 8</a> style conventions, and we recommend you set up your editor to automatically indicate non-conforming styles.
You can check your contributions against these conventions each time you commit using the <a href="https://pre-commit.com/">pre-commit</a> hooks, which we also run on CI.
To set them up, first ensure you have the pre-commit tool installed, for example:</p>
<pre><code>python -m pip install pre-commit
</code></pre>
<p>Then run:</p>
<pre><code>pre-commit install
</code></pre>
<h2 id="testing"><a class="toclink" href="#testing">Testing</a></h2> <h2 id="testing"><a class="toclink" href="#testing">Testing</a></h2>
<p>To run the tests, clone the repository, and then:</p> <p>To run the tests, clone the repository, and then:</p>
<pre><code># Setup the virtual environment <pre><code># Setup the virtual environment
@ -536,15 +543,6 @@ pip install -r requirements.txt
<p>Run using a more concise output style.</p> <p>Run using a more concise output style.</p>
<pre><code>./runtests.py -q <pre><code>./runtests.py -q
</code></pre> </code></pre>
<p>Run the tests using a more concise output style, no coverage, no flake8.</p>
<pre><code>./runtests.py --fast
</code></pre>
<p>Don't run the flake8 code linting.</p>
<pre><code>./runtests.py --nolint
</code></pre>
<p>Only run the flake8 code linting, don't run the tests.</p>
<pre><code>./runtests.py --lintonly
</code></pre>
<p>Run the tests for a given test case.</p> <p>Run the tests for a given test case.</p>
<pre><code>./runtests.py MyTestCase <pre><code>./runtests.py MyTestCase
</code></pre> </code></pre>
@ -565,9 +563,9 @@ pip install -r requirements.txt
<p>It's also useful to remember that if you have an outstanding pull request then pushing new commits to your GitHub repo will also automatically update the pull requests.</p> <p>It's also useful to remember that if you have an outstanding pull request then pushing new commits to your GitHub repo will also automatically update the pull requests.</p>
<p>GitHub's documentation for working on pull requests is <a href="https://help.github.com/articles/using-pull-requests">available here</a>.</p> <p>GitHub's documentation for working on pull requests is <a href="https://help.github.com/articles/using-pull-requests">available here</a>.</p>
<p>Always run the tests before submitting pull requests, and ideally run <code>tox</code> in order to check that your modifications are compatible on all supported versions of Python and Django.</p> <p>Always run the tests before submitting pull requests, and ideally run <code>tox</code> in order to check that your modifications are compatible on all supported versions of Python and Django.</p>
<p>Once you've made a pull request take a look at the Travis build status in the GitHub interface and make sure the tests are running as you'd expect.</p> <p>Once you've made a pull request take a look at the build status in the GitHub interface and make sure the tests are running as you'd expect.</p>
<p><img alt="Travis status" src="../../img/travis-status.png" /></p> <p><img alt="Build status" src="../../img/build-status.png" /></p>
<p><em>Above: Travis build notifications</em></p> <p><em>Above: build notifications</em></p>
<h2 id="managing-compatibility-issues"><a class="toclink" href="#managing-compatibility-issues">Managing compatibility issues</a></h2> <h2 id="managing-compatibility-issues"><a class="toclink" href="#managing-compatibility-issues">Managing compatibility issues</a></h2>
<p>Sometimes, in order to ensure your code works on various different versions of Django, Python or third party libraries, you'll need to run slightly different code depending on the environment. Any code that branches in this way should be isolated into the <code>compat.py</code> module, and should provide a single common interface that the rest of the codebase can use.</p> <p>Sometimes, in order to ensure your code works on various different versions of Django, Python or third party libraries, you'll need to run slightly different code depending on the environment. Any code that branches in this way should be isolated into the <code>compat.py</code> module, and should provide a single common interface that the rest of the codebase can use.</p>
<h1 id="documentation"><a class="toclink" href="#documentation">Documentation</a></h1> <h1 id="documentation"><a class="toclink" href="#documentation">Documentation</a></h1>

View File

@ -517,7 +517,12 @@
</code></pre> </code></pre>
<hr /> <hr />
<h2 id="312x-series"><a class="toclink" href="#312x-series">3.12.x series</a></h2> <h2 id="312x-series"><a class="toclink" href="#312x-series">3.12.x series</a></h2>
<h3 id="3122"><a class="toclink" href="#3122">3.12.2</a></h3> <h3 id="3124"><a class="toclink" href="#3124">3.12.4</a></h3>
<p>Date: 26th March 2021</p>
<ul>
<li>Revert use of <code>deque</code> instead of <code>list</code> for tracking throttling <code>.history</code>. (Due to incompatibility with DjangoRedis cache backend. See #7870) [#7872]</li>
</ul>
<h3 id="3123"><a class="toclink" href="#3123">3.12.3</a></h3>
<p>Date: 25th March 2021</p> <p>Date: 25th March 2021</p>
<ul> <ul>
<li>Properly handle ATOMIC_REQUESTS when multiple database configurations are used. [#7739]</li> <li>Properly handle ATOMIC_REQUESTS when multiple database configurations are used. [#7739]</li>
@ -532,7 +537,7 @@
<li>Don't include model properties as automatically generated ordering fields with <code>OrderingFilter</code>. [#7609]</li> <li>Don't include model properties as automatically generated ordering fields with <code>OrderingFilter</code>. [#7609]</li>
<li>Use <code>deque</code> instead of <code>list</code> for tracking throttling <code>.history</code>. [#7849]</li> <li>Use <code>deque</code> instead of <code>list</code> for tracking throttling <code>.history</code>. [#7849]</li>
</ul> </ul>
<h3 id="3122_1"><a class="toclink" href="#3122_1">3.12.2</a></h3> <h3 id="3122"><a class="toclink" href="#3122">3.12.2</a></h3>
<p>Date: 13th October 2020</p> <p>Date: 13th October 2020</p>
<ul> <ul>
<li>Fix issue if <code>rest_framework.authtoken.models</code> is imported, but <code>rest_framework.authtoken</code> is not in INSTALLED_APPS. [#7571]</li> <li>Fix issue if <code>rest_framework.authtoken.models</code> is imported, but <code>rest_framework.authtoken</code> is not in INSTALLED_APPS. [#7571]</li>

View File

@ -414,7 +414,7 @@
</li> </li>
<li> <li>
<a href="#how-to-create-a-third-party-package">How to create a Third Party Package</a> <a href="#creating-a-third-party-package">Creating a Third Party Package</a>
</li> </li>
<li> <li>
@ -446,99 +446,8 @@
<p>We <strong>support</strong>, <strong>encourage</strong> and <strong>strongly favor</strong> the creation of Third Party Packages to encapsulate new behavior rather than adding additional functionality directly to Django REST Framework.</p> <p>We <strong>support</strong>, <strong>encourage</strong> and <strong>strongly favor</strong> the creation of Third Party Packages to encapsulate new behavior rather than adding additional functionality directly to Django REST Framework.</p>
<p>We aim to make creating third party packages as easy as possible, whilst keeping a <strong>simple</strong> and <strong>well maintained</strong> core API. By promoting third party packages we ensure that the responsibility for a package remains with its author. If a package proves suitably popular it can always be considered for inclusion into the core REST framework.</p> <p>We aim to make creating third party packages as easy as possible, whilst keeping a <strong>simple</strong> and <strong>well maintained</strong> core API. By promoting third party packages we ensure that the responsibility for a package remains with its author. If a package proves suitably popular it can always be considered for inclusion into the core REST framework.</p>
<p>If you have an idea for a new feature please consider how it may be packaged as a Third Party Package. We're always happy to discuss ideas on the <a href="https://groups.google.com/forum/#!forum/django-rest-framework">Mailing List</a>.</p> <p>If you have an idea for a new feature please consider how it may be packaged as a Third Party Package. We're always happy to discuss ideas on the <a href="https://groups.google.com/forum/#!forum/django-rest-framework">Mailing List</a>.</p>
<h2 id="how-to-create-a-third-party-package"><a class="toclink" href="#how-to-create-a-third-party-package">How to create a Third Party Package</a></h2> <h2 id="creating-a-third-party-package"><a class="toclink" href="#creating-a-third-party-package">Creating a Third Party Package</a></h2>
<h3 id="creating-your-package"><a class="toclink" href="#creating-your-package">Creating your package</a></h3> <h3 id="version-compatibility"><a class="toclink" href="#version-compatibility">Version compatibility</a></h3>
<p>You can use <a href="https://github.com/jpadilla/cookiecutter-django-rest-framework">this cookiecutter template</a> for creating reusable Django REST Framework packages quickly. Cookiecutter creates projects from project templates. While optional, this cookiecutter template includes best practices from Django REST framework and other packages, as well as a Travis CI configuration, Tox configuration, and a sane setup.py for easy PyPI registration/distribution.</p>
<p>Note: Let us know if you have an alternate cookiecutter package so we can also link to it.</p>
<h4 id="running-the-initial-cookiecutter-command"><a class="toclink" href="#running-the-initial-cookiecutter-command">Running the initial cookiecutter command</a></h4>
<p>To run the initial cookiecutter command, you'll first need to install the Python <code>cookiecutter</code> package.</p>
<pre><code>$ pip install cookiecutter
</code></pre>
<p>Once <code>cookiecutter</code> is installed just run the following to create a new project.</p>
<pre><code>$ cookiecutter gh:jpadilla/cookiecutter-django-rest-framework
</code></pre>
<p>You'll be prompted for some questions, answer them, then it'll create your Python package in the current working directory based on those values.</p>
<pre><code>full_name (default is "Your full name here")? Johnny Appleseed
email (default is "you@example.com")? jappleseed@example.com
github_username (default is "yourname")? jappleseed
pypi_project_name (default is "dj-package")? djangorestframework-custom-auth
repo_name (default is "dj-package")? django-rest-framework-custom-auth
app_name (default is "djpackage")? custom_auth
project_short_description (default is "Your project description goes here")?
year (default is "2014")?
version (default is "0.1.0")?
</code></pre>
<h4 id="getting-it-onto-github"><a class="toclink" href="#getting-it-onto-github">Getting it onto GitHub</a></h4>
<p>To put your project up on GitHub, you'll need a repository for it to live in. You can create a new repository <a href="https://github.com/new">here</a>. If you need help, check out the <a href="https://help.github.com/articles/create-a-repo/">Create A Repo</a> article on GitHub.</p>
<h4 id="adding-to-travis-ci"><a class="toclink" href="#adding-to-travis-ci">Adding to Travis CI</a></h4>
<p>We recommend using <a href="https://travis-ci.org">Travis CI</a>, a hosted continuous integration service which integrates well with GitHub and is free for public repositories.</p>
<p>To get started with Travis CI, <a href="https://travis-ci.org">sign in</a> with your GitHub account. Once you're signed in, go to your <a href="https://travis-ci.org/profile">profile page</a> and enable the service hook for the repository you want.</p>
<p>If you use the cookiecutter template, your project will already contain a <code>.travis.yml</code> file which Travis CI will use to build your project and run tests. By default, builds are triggered every time you push to your repository or create Pull Request.</p>
<h4 id="uploading-to-pypi"><a class="toclink" href="#uploading-to-pypi">Uploading to PyPI</a></h4>
<p>Once you've got at least a prototype working and tests running, you should publish it on PyPI to allow others to install it via <code>pip</code>.</p>
<p>You must <a href="https://pypi.org/account/register/">register</a> an account before publishing to PyPI.</p>
<p>To register your package on PyPI run the following command.</p>
<pre><code>$ python setup.py register
</code></pre>
<p>If this is the first time publishing to PyPI, you'll be prompted to login.</p>
<p>Note: Before publishing you'll need to make sure you have the latest pip that supports <code>wheel</code> as well as install the <code>wheel</code> package.</p>
<pre><code>$ pip install --upgrade pip
$ pip install wheel
</code></pre>
<p>After this, every time you want to release a new version on PyPI just run the following command.</p>
<pre><code>$ python setup.py publish
You probably want to also tag the version now:
git tag -a {0} -m 'version 0.1.0'
git push --tags
</code></pre>
<p>After releasing a new version to PyPI, it's always a good idea to tag the version and make available as a GitHub Release.</p>
<p>We recommend to follow <a href="https://semver.org/">Semantic Versioning</a> for your package's versions.</p>
<h3 id="development"><a class="toclink" href="#development">Development</a></h3>
<h4 id="version-requirements"><a class="toclink" href="#version-requirements">Version requirements</a></h4>
<p>The cookiecutter template assumes a set of supported versions will be provided for Python and Django. Make sure you correctly update your requirements, docs, <code>tox.ini</code>, <code>.travis.yml</code>, and <code>setup.py</code> to match the set of versions you wish to support.</p>
<h4 id="tests"><a class="toclink" href="#tests">Tests</a></h4>
<p>The cookiecutter template includes a <code>runtests.py</code> which uses the <code>pytest</code> package as a test runner.</p>
<p>Before running, you'll need to install a couple test requirements.</p>
<pre><code>$ pip install -r requirements.txt
</code></pre>
<p>Once requirements installed, you can run <code>runtests.py</code>.</p>
<pre><code>$ ./runtests.py
</code></pre>
<p>Run using a more concise output style.</p>
<pre><code>$ ./runtests.py -q
</code></pre>
<p>Run the tests using a more concise output style, no coverage, no flake8.</p>
<pre><code>$ ./runtests.py --fast
</code></pre>
<p>Don't run the flake8 code linting.</p>
<pre><code>$ ./runtests.py --nolint
</code></pre>
<p>Only run the flake8 code linting, don't run the tests.</p>
<pre><code>$ ./runtests.py --lintonly
</code></pre>
<p>Run the tests for a given test case.</p>
<pre><code>$ ./runtests.py MyTestCase
</code></pre>
<p>Run the tests for a given test method.</p>
<pre><code>$ ./runtests.py MyTestCase.test_this_method
</code></pre>
<p>Shorter form to run the tests for a given test method.</p>
<pre><code>$ ./runtests.py test_this_method
</code></pre>
<p>To run your tests against multiple versions of Python as different versions of requirements such as Django we recommend using <code>tox</code>. <a href="https://tox.readthedocs.io/en/latest/">Tox</a> is a generic virtualenv management and test command line tool.</p>
<p>First, install <code>tox</code> globally.</p>
<pre><code>$ pip install tox
</code></pre>
<p>To run <code>tox</code>, just simply run:</p>
<pre><code>$ tox
</code></pre>
<p>To run a particular <code>tox</code> environment:</p>
<pre><code>$ tox -e envlist
</code></pre>
<p><code>envlist</code> is a comma-separated value to that specifies the environments to run tests against. To view a list of all possible test environments, run:</p>
<pre><code>$ tox -l
</code></pre>
<h4 id="version-compatibility"><a class="toclink" href="#version-compatibility">Version compatibility</a></h4>
<p>Sometimes, in order to ensure your code works on various different versions of Django, Python or third party libraries, you'll need to run slightly different code depending on the environment. Any code that branches in this way should be isolated into a <code>compat.py</code> module, and should provide a single common interface that the rest of the codebase can use.</p> <p>Sometimes, in order to ensure your code works on various different versions of Django, Python or third party libraries, you'll need to run slightly different code depending on the environment. Any code that branches in this way should be isolated into a <code>compat.py</code> module, and should provide a single common interface that the rest of the codebase can use.</p>
<p>Check out Django REST framework's <a href="https://github.com/encode/django-rest-framework/blob/master/rest_framework/compat.py">compat.py</a> for an example.</p> <p>Check out Django REST framework's <a href="https://github.com/encode/django-rest-framework/blob/master/rest_framework/compat.py">compat.py</a> for an example.</p>
<h3 id="once-your-package-is-available"><a class="toclink" href="#once-your-package-is-available">Once your package is available</a></h3> <h3 id="once-your-package-is-available"><a class="toclink" href="#once-your-package-is-available">Once your package is available</a></h3>
@ -561,7 +470,7 @@ You probably want to also tag the version now:
<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> <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>
<li><a href="https://github.com/Tivix/django-rest-auth/">django-rest-auth</a> - Provides a set of REST API endpoints for registration, authentication (including social media authentication), password reset, retrieve and update user details, etc.</li> <li><a href="https://github.com/iMerica/dj-rest-auth">dj-rest-auth</a> - Provides a set of REST API endpoints for registration, authentication (including social media authentication), password reset, retrieve and update user details, etc.</li>
<li><a href="https://github.com/ByteInternet/drf-oidc-auth">drf-oidc-auth</a> - Implements OpenID Connect token authentication for DRF.</li> <li><a href="https://github.com/ByteInternet/drf-oidc-auth">drf-oidc-auth</a> - Implements OpenID Connect token authentication for DRF.</li>
<li><a href="https://github.com/aaronn/django-rest-framework-passwordless">drfpasswordless</a> - Adds (Medium, Square Cash inspired) passwordless logins and signups via email and mobile numbers.</li> <li><a href="https://github.com/aaronn/django-rest-framework-passwordless">drfpasswordless</a> - Adds (Medium, Square Cash inspired) passwordless logins and signups via email and mobile numbers.</li>
<li><a href="https://github.com/celiao/django-rest-authemail">django-rest-authemail</a> - Provides a RESTful API for user signup and authentication using email addresses.</li> <li><a href="https://github.com/celiao/django-rest-authemail">django-rest-authemail</a> - Provides a RESTful API for user signup and authentication using email addresses.</li>

View File

@ -500,7 +500,7 @@
<h2 id="articles"><a class="toclink" href="#articles">Articles</a></h2> <h2 id="articles"><a class="toclink" href="#articles">Articles</a></h2>
<ul> <ul>
<li><a href="https://www.dabapps.com/blog/api-performance-profiling-django-rest-framework/">Web API performance: Profiling Django REST Framework</a></li> <li><a href="https://www.dabapps.com/blog/api-performance-profiling-django-rest-framework/">Web API performance: Profiling Django REST Framework</a></li>
<li><a href="https://bnotions.com/api-development-with-django-and-django-rest-framework/">API Development with Django and Django REST Framework</a></li> <li><a href="https://bnotions.com/news-and-insights/api-development-with-django-and-django-rest-framework/">API Development with Django and Django REST Framework</a></li>
<li><a href="https://web.archive.org/web/20180104205117/http://machinalis.com/blog/pandas-django-rest-framework-bokeh/">Integrating Pandas, Django REST Framework and Bokeh</a></li> <li><a href="https://web.archive.org/web/20180104205117/http://machinalis.com/blog/pandas-django-rest-framework-bokeh/">Integrating Pandas, Django REST Framework and Bokeh</a></li>
<li><a href="https://web.archive.org/web/20180104205043/https://machinalis.com/blog/controlling-uncertainty-on-web-applications-and-apis/">Controlling Uncertainty on Web Applications and APIs</a></li> <li><a href="https://web.archive.org/web/20180104205043/https://machinalis.com/blog/controlling-uncertainty-on-web-applications-and-apis/">Controlling Uncertainty on Web Applications and APIs</a></li>
<li><a href="https://web.archive.org/web/20180104205059/http://machinalis.com/blog/full-text-search-on-django-rest-framework/">Full Text Search in Django REST Framework with Database Backends</a></li> <li><a href="https://web.archive.org/web/20180104205059/http://machinalis.com/blog/full-text-search-on-django-rest-framework/">Full Text Search in Django REST Framework with Database Backends</a></li>
@ -510,6 +510,7 @@
<li><a href="https://chatbotslife.com/chatbot-using-django-rest-framework-api-ai-slack-part-1-3-69c7e38b7b1e#.g2aceuncf">Chatbot Using Django REST Framework + api.ai + SlackPart 1/3</a></li> <li><a href="https://chatbotslife.com/chatbot-using-django-rest-framework-api-ai-slack-part-1-3-69c7e38b7b1e#.g2aceuncf">Chatbot Using Django REST Framework + api.ai + SlackPart 1/3</a></li>
<li><a href="https://blog.levit.be/new-django-admin-with-emberjs-what-are-the-news/">New Django Admin with DRF and EmberJS... What are the News?</a></li> <li><a href="https://blog.levit.be/new-django-admin-with-emberjs-what-are-the-news/">New Django Admin with DRF and EmberJS... What are the News?</a></li>
<li><a href="https://medium.com/django-rest-framework">Blog posts about Django REST Framework</a></li> <li><a href="https://medium.com/django-rest-framework">Blog posts about Django REST Framework</a></li>
<li><a href="https://doordash.engineering/2013/10/07/implementing-rest-apis-with-embedded-privacy/">Implementing Rest APIs With Embedded Privacy</a></li>
</ul> </ul>
<h3 id="documentations"><a class="toclink" href="#documentations">Documentations</a></h3> <h3 id="documentations"><a class="toclink" href="#documentations">Documentations</a></h3>
<ul> <ul>

View File

@ -37,7 +37,7 @@ body.index-page #main-content iframe.github-star-button {
margin-right: -15px; margin-right: -15px;
} }
/* Travis CI and PyPI badge */ /* CI and PyPI badge */
body.index-page #main-content img.status-badge { body.index-page #main-content img.status-badge {
float: right; float: right;
margin-right: 8px; margin-right: 8px;

BIN
img/build-status.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

View File

@ -498,8 +498,8 @@
<p class="badges" height=20px> <p class="badges" height=20px>
<iframe src="https://ghbtns.com/github-btn.html?user=encode&amp;repo=django-rest-framework&amp;type=watch&amp;count=true" class="github-star-button" allowtransparency="true" frameborder="0" scrolling="0" width="110px" height="20px"></iframe> <iframe src="https://ghbtns.com/github-btn.html?user=encode&amp;repo=django-rest-framework&amp;type=watch&amp;count=true" class="github-star-button" allowtransparency="true" frameborder="0" scrolling="0" width="110px" height="20px"></iframe>
<a href="https://travis-ci.org/encode/django-rest-framework?branch=master"> <a href="https://github.com/encode/django-rest-framework/actions/workflows/main.yml">
<img src="https://secure.travis-ci.org/encode/django-rest-framework.svg?branch=master" class="status-badge"> <img src="https://github.com/encode/django-rest-framework/actions/workflows/main.yml/badge.svg" class="status-badge">
</a> </a>
<a href="https://pypi.org/project/djangorestframework/"> <a href="https://pypi.org/project/djangorestframework/">
@ -539,7 +539,7 @@ continued development by <strong><a href="community/funding/">signing up for a p
<p><em>Every single sign-up helps us make REST framework long-term financially sustainable.</em></p> <p><em>Every single sign-up helps us make REST framework long-term financially sustainable.</em></p>
<ul class="premium-promo promo"> <ul class="premium-promo promo">
<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://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/try-the-api/?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="https://getstream.io/?utm_source=drf&utm_medium=sponsorship&utm_content=developer" style="background-image: url(https://fund-rest-framework.s3.amazonaws.com/stream-130.png)">Stream</a></li>
<li><a href="https://software.esg-usa.com" style="background-image: url(https://fund-rest-framework.s3.amazonaws.com/esg-new-logo.png)">ESG</a></li> <li><a href="https://software.esg-usa.com" style="background-image: url(https://fund-rest-framework.s3.amazonaws.com/esg-new-logo.png)">ESG</a></li>
<li><a href="https://rollbar.com" style="background-image: url(https://fund-rest-framework.s3.amazonaws.com/rollbar2.png)">Rollbar</a></li> <li><a href="https://rollbar.com" style="background-image: url(https://fund-rest-framework.s3.amazonaws.com/rollbar2.png)">Rollbar</a></li>
<li><a href="https://retool.com/?utm_source=djangorest&utm_medium=sponsorship" style="background-image: url(https://fund-rest-framework.s3.amazonaws.com/retool-sidebar.png)">Retool</a></li> <li><a href="https://retool.com/?utm_source=djangorest&utm_medium=sponsorship" style="background-image: url(https://fund-rest-framework.s3.amazonaws.com/retool-sidebar.png)">Retool</a></li>
@ -547,13 +547,13 @@ continued development by <strong><a href="community/funding/">signing up for a p
</ul> </ul>
<div style="clear: both; padding-bottom: 20px;"></div> <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">wonderful sponsors</a>, and in particular to our premium backers, <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>, <a href="https://software.esg-usa.com/">ESG</a>, <a href="https://rollbar.com/?utm_source=django&amp;utm_medium=sponsorship&amp;utm_campaign=freetrial">Rollbar</a>, <a href="https://cadre.com">Cadre</a>, <a href="https://hubs.ly/H0f30Lf0">Kloudless</a>, <a href="https://lightsonsoftware.com">Lights On Software</a>, <a href="https://retool.com/?utm_source=djangorest&amp;utm_medium=sponsorship">Retool</a>, and <a href="https://bit.io/jobs?utm_source=DRF&amp;utm_medium=sponsor&amp;utm_campaign=DRF_sponsorship">bit.io</a>.</em></p> <p><em>Many thanks to all our <a href="https://fund.django-rest-framework.org/topics/funding/#our-sponsors">wonderful sponsors</a>, and in particular to our premium backers, <a href="https://getsentry.com/welcome/">Sentry</a>, <a href="https://getstream.io/?utm_source=drf&amp;utm_medium=sponsorship&amp;utm_content=developer">Stream</a>, <a href="https://software.esg-usa.com/">ESG</a>, <a href="https://rollbar.com/?utm_source=django&amp;utm_medium=sponsorship&amp;utm_campaign=freetrial">Rollbar</a>, <a href="https://cadre.com">Cadre</a>, <a href="https://hubs.ly/H0f30Lf0">Kloudless</a>, <a href="https://lightsonsoftware.com">Lights On Software</a>, <a href="https://retool.com/?utm_source=djangorest&amp;utm_medium=sponsorship">Retool</a>, and <a href="https://bit.io/jobs?utm_source=DRF&amp;utm_medium=sponsor&amp;utm_campaign=DRF_sponsorship">bit.io</a>.</em></p>
<hr /> <hr />
<h2 id="requirements"><a class="toclink" href="#requirements">Requirements</a></h2> <h2 id="requirements"><a class="toclink" href="#requirements">Requirements</a></h2>
<p>REST framework requires the following:</p> <p>REST framework requires the following:</p>
<ul> <ul>
<li>Python (3.5, 3.6, 3.7, 3.8, 3.9)</li> <li>Python (3.5, 3.6, 3.7, 3.8, 3.9)</li>
<li>Django (2.2, 3.0, 3.1)</li> <li>Django (2.2, 3.0, 3.1, 3.2)</li>
</ul> </ul>
<p>We <strong>highly recommend</strong> and only officially support the latest patch release of <p>We <strong>highly recommend</strong> and only officially support the latest patch release of
each Python and Django series.</p> each Python and Django series.</p>
@ -636,7 +636,7 @@ urlpatterns = [
the repository, run the test suite and contribute changes back to REST the repository, run the test suite and contribute changes back to REST
Framework.</p> Framework.</p>
<h2 id="support"><a class="toclink" href="#support">Support</a></h2> <h2 id="support"><a class="toclink" href="#support">Support</a></h2>
<p>For support please see the <a href="https://groups.google.com/forum/?fromgroups#!forum/django-rest-framework">REST framework discussion group</a>, try the <code>#restframework</code> channel on <code>irc.freenode.net</code>, search <a href="https://botbot.me/freenode/restframework/">the IRC archives</a>, or raise a question on <a href="https://stackoverflow.com/">Stack Overflow</a>, making sure to include the <a href="https://stackoverflow.com/questions/tagged/django-rest-framework">'django-rest-framework'</a> tag.</p> <p>For support please see the <a href="https://groups.google.com/forum/?fromgroups#!forum/django-rest-framework">REST framework discussion group</a>, try the <code>#restframework</code> channel on <code>irc.libera.chat</code>, or raise a question on <a href="https://stackoverflow.com/">Stack Overflow</a>, making sure to include the <a href="https://stackoverflow.com/questions/tagged/django-rest-framework">'django-rest-framework'</a> tag.</p>
<p>For priority support please sign up for a <a href="https://fund.django-rest-framework.org/topics/funding/">professional or premium sponsorship plan</a>.</p> <p>For priority support please sign up for a <a href="https://fund.django-rest-framework.org/topics/funding/">professional or premium sponsorship plan</a>.</p>
<h2 id="security"><a class="toclink" href="#security">Security</a></h2> <h2 id="security"><a class="toclink" href="#security">Security</a></h2>
<p>If you believe youve found something in Django REST framework which has security implications, please <strong>do not raise the issue in a public forum</strong>.</p> <p>If you believe youve found something in Django REST framework which has security implications, please <strong>do not raise the issue in a public forum</strong>.</p>

File diff suppressed because one or more lines are too long

View File

@ -1,267 +1,267 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"><url> <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"><url>
<loc>https://www.django-rest-framework.org/</loc> <loc>https://www.django-rest-framework.org/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/tutorial/quickstart/</loc> <loc>https://www.django-rest-framework.org/tutorial/quickstart/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/tutorial/1-serialization/</loc> <loc>https://www.django-rest-framework.org/tutorial/1-serialization/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/tutorial/2-requests-and-responses/</loc> <loc>https://www.django-rest-framework.org/tutorial/2-requests-and-responses/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/tutorial/3-class-based-views/</loc> <loc>https://www.django-rest-framework.org/tutorial/3-class-based-views/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/tutorial/4-authentication-and-permissions/</loc> <loc>https://www.django-rest-framework.org/tutorial/4-authentication-and-permissions/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/tutorial/5-relationships-and-hyperlinked-apis/</loc> <loc>https://www.django-rest-framework.org/tutorial/5-relationships-and-hyperlinked-apis/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/tutorial/6-viewsets-and-routers/</loc> <loc>https://www.django-rest-framework.org/tutorial/6-viewsets-and-routers/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/api-guide/requests/</loc> <loc>https://www.django-rest-framework.org/api-guide/requests/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/api-guide/responses/</loc> <loc>https://www.django-rest-framework.org/api-guide/responses/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/api-guide/views/</loc> <loc>https://www.django-rest-framework.org/api-guide/views/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/api-guide/generic-views/</loc> <loc>https://www.django-rest-framework.org/api-guide/generic-views/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/api-guide/viewsets/</loc> <loc>https://www.django-rest-framework.org/api-guide/viewsets/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/api-guide/routers/</loc> <loc>https://www.django-rest-framework.org/api-guide/routers/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/api-guide/parsers/</loc> <loc>https://www.django-rest-framework.org/api-guide/parsers/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/api-guide/renderers/</loc> <loc>https://www.django-rest-framework.org/api-guide/renderers/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/api-guide/serializers/</loc> <loc>https://www.django-rest-framework.org/api-guide/serializers/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/api-guide/fields/</loc> <loc>https://www.django-rest-framework.org/api-guide/fields/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/api-guide/relations/</loc> <loc>https://www.django-rest-framework.org/api-guide/relations/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/api-guide/validators/</loc> <loc>https://www.django-rest-framework.org/api-guide/validators/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/api-guide/authentication/</loc> <loc>https://www.django-rest-framework.org/api-guide/authentication/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/api-guide/permissions/</loc> <loc>https://www.django-rest-framework.org/api-guide/permissions/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/api-guide/caching/</loc> <loc>https://www.django-rest-framework.org/api-guide/caching/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/api-guide/throttling/</loc> <loc>https://www.django-rest-framework.org/api-guide/throttling/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/api-guide/filtering/</loc> <loc>https://www.django-rest-framework.org/api-guide/filtering/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/api-guide/pagination/</loc> <loc>https://www.django-rest-framework.org/api-guide/pagination/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/api-guide/versioning/</loc> <loc>https://www.django-rest-framework.org/api-guide/versioning/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/api-guide/content-negotiation/</loc> <loc>https://www.django-rest-framework.org/api-guide/content-negotiation/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/api-guide/metadata/</loc> <loc>https://www.django-rest-framework.org/api-guide/metadata/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/api-guide/schemas/</loc> <loc>https://www.django-rest-framework.org/api-guide/schemas/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/api-guide/format-suffixes/</loc> <loc>https://www.django-rest-framework.org/api-guide/format-suffixes/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/api-guide/reverse/</loc> <loc>https://www.django-rest-framework.org/api-guide/reverse/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/api-guide/exceptions/</loc> <loc>https://www.django-rest-framework.org/api-guide/exceptions/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/api-guide/status-codes/</loc> <loc>https://www.django-rest-framework.org/api-guide/status-codes/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/api-guide/testing/</loc> <loc>https://www.django-rest-framework.org/api-guide/testing/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/api-guide/settings/</loc> <loc>https://www.django-rest-framework.org/api-guide/settings/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/topics/documenting-your-api/</loc> <loc>https://www.django-rest-framework.org/topics/documenting-your-api/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/topics/api-clients/</loc> <loc>https://www.django-rest-framework.org/topics/api-clients/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/topics/internationalization/</loc> <loc>https://www.django-rest-framework.org/topics/internationalization/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/topics/ajax-csrf-cors/</loc> <loc>https://www.django-rest-framework.org/topics/ajax-csrf-cors/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/topics/html-and-forms/</loc> <loc>https://www.django-rest-framework.org/topics/html-and-forms/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/topics/browser-enhancements/</loc> <loc>https://www.django-rest-framework.org/topics/browser-enhancements/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/topics/browsable-api/</loc> <loc>https://www.django-rest-framework.org/topics/browsable-api/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/topics/rest-hypermedia-hateoas/</loc> <loc>https://www.django-rest-framework.org/topics/rest-hypermedia-hateoas/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/community/tutorials-and-resources/</loc> <loc>https://www.django-rest-framework.org/community/tutorials-and-resources/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/community/third-party-packages/</loc> <loc>https://www.django-rest-framework.org/community/third-party-packages/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/community/contributing/</loc> <loc>https://www.django-rest-framework.org/community/contributing/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/community/project-management/</loc> <loc>https://www.django-rest-framework.org/community/project-management/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/community/release-notes/</loc> <loc>https://www.django-rest-framework.org/community/release-notes/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/community/3.12-announcement/</loc> <loc>https://www.django-rest-framework.org/community/3.12-announcement/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/community/3.11-announcement/</loc> <loc>https://www.django-rest-framework.org/community/3.11-announcement/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/community/3.10-announcement/</loc> <loc>https://www.django-rest-framework.org/community/3.10-announcement/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/community/3.9-announcement/</loc> <loc>https://www.django-rest-framework.org/community/3.9-announcement/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/community/3.8-announcement/</loc> <loc>https://www.django-rest-framework.org/community/3.8-announcement/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/community/3.7-announcement/</loc> <loc>https://www.django-rest-framework.org/community/3.7-announcement/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/community/3.6-announcement/</loc> <loc>https://www.django-rest-framework.org/community/3.6-announcement/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/community/3.5-announcement/</loc> <loc>https://www.django-rest-framework.org/community/3.5-announcement/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/community/3.4-announcement/</loc> <loc>https://www.django-rest-framework.org/community/3.4-announcement/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/community/3.3-announcement/</loc> <loc>https://www.django-rest-framework.org/community/3.3-announcement/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/community/3.2-announcement/</loc> <loc>https://www.django-rest-framework.org/community/3.2-announcement/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/community/3.1-announcement/</loc> <loc>https://www.django-rest-framework.org/community/3.1-announcement/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/community/3.0-announcement/</loc> <loc>https://www.django-rest-framework.org/community/3.0-announcement/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/community/kickstarter-announcement/</loc> <loc>https://www.django-rest-framework.org/community/kickstarter-announcement/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/community/mozilla-grant/</loc> <loc>https://www.django-rest-framework.org/community/mozilla-grant/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/community/funding/</loc> <loc>https://www.django-rest-framework.org/community/funding/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url><url> </url><url>
<loc>https://www.django-rest-framework.org/community/jobs/</loc> <loc>https://www.django-rest-framework.org/community/jobs/</loc>
<lastmod>2021-03-25</lastmod> <lastmod>2021-09-10</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url> </url>
</urlset> </urlset>

Binary file not shown.

View File

@ -726,7 +726,7 @@ Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C. Quit the server with CONTROL-C.
</code></pre> </code></pre>
<p>In another terminal window, we can test the server.</p> <p>In another terminal window, we can test the server.</p>
<p>We can test our API using <a href="https://curl.haxx.se/">curl</a> or <a href="https://github.com/jakubroztocil/httpie#installation">httpie</a>. Httpie is a user friendly http client that's written in Python. Let's install that.</p> <p>We can test our API using <a href="https://curl.haxx.se/">curl</a> or <a href="https://github.com/httpie/httpie#installation">httpie</a>. Httpie is a user friendly http client that's written in Python. Let's install that.</p>
<p>You can install httpie using pip:</p> <p>You can install httpie using pip:</p>
<pre><code>pip install httpie <pre><code>pip install httpie
</code></pre> </code></pre>

View File

@ -471,7 +471,6 @@ def api_root(request, format=None):
<p>The other thing we need to consider when creating the code highlight view is that there's no existing concrete generic view that we can use. We're not returning an object instance, but instead a property of an object instance.</p> <p>The other thing we need to consider when creating the code highlight view is that there's no existing concrete generic view that we can use. We're not returning an object instance, but instead a property of an object instance.</p>
<p>Instead of using a concrete generic view, we'll use the base class for representing instances, and create our own <code>.get()</code> method. In your <code>snippets/views.py</code> add:</p> <p>Instead of using a concrete generic view, we'll use the base class for representing instances, and create our own <code>.get()</code> method. In your <code>snippets/views.py</code> add:</p>
<pre><code>from rest_framework import renderers <pre><code>from rest_framework import renderers
from rest_framework.response import Response
class SnippetHighlight(generics.GenericAPIView): class SnippetHighlight(generics.GenericAPIView):
queryset = Snippet.objects.all() queryset = Snippet.objects.all()