mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-04-23 02:22:14 +03:00
Deployed 0ab527a3
with MkDocs version: 0.16.3
This commit is contained in:
parent
952f4e3cdc
commit
aaee4bd6e6
|
@ -436,7 +436,7 @@ provided in Django.</p>
|
|||
<h2 id="using-cache-with-apiview-and-viewsets"><a class="toclink" href="#using-cache-with-apiview-and-viewsets">Using cache with apiview and viewsets</a></h2>
|
||||
<p>Django provides a <a href="https://docs.djangoproject.com/en/dev/topics/class-based-views/intro/#decorating-the-class"><code>method_decorator</code></a> to use
|
||||
decorators with class based views. This can be used with
|
||||
with other cache decorators such as <a href="https://docs.djangoproject.com/en/dev/topics/cache/#the-per-view-cache"><code>cache_page</code></a> and
|
||||
other cache decorators such as <a href="https://docs.djangoproject.com/en/dev/topics/cache/#the-per-view-cache"><code>cache_page</code></a> and
|
||||
<a href="https://docs.djangoproject.com/en/dev/topics/http/decorators/#django.views.decorators.vary.vary_on_cookie"><code>vary_on_cookie</code></a>.</p>
|
||||
<pre><code class="python">from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
|
|
|
@ -707,7 +707,14 @@ color_channel = serializers.ChoiceField(
|
|||
<h2 id="booleanfield"><a class="toclink" href="#booleanfield">BooleanField</a></h2>
|
||||
<p>A boolean representation.</p>
|
||||
<p>When using HTML encoded form input be aware that omitting a value will always be treated as setting a field to <code>False</code>, even if it has a <code>default=True</code> option specified. This is because HTML checkbox inputs represent the unchecked state by omitting the value, so REST framework treats omission as if it is an empty checkbox input.</p>
|
||||
<p>Note that default <code>BooleanField</code> instances will be generated with a <code>required=False</code> option (since Django <code>models.BooleanField</code> is always <code>blank=True</code>). If you want to change this behaviour explicitly declare the <code>BooleanField</code> on the serializer class.</p>
|
||||
<p>Note that Django 2.1 removed the <code>blank</code> kwarg from <code>models.BooleanField</code>.
|
||||
Prior to Django 2.1 <code>models.BooleanField</code> fields were always <code>blank=True</code>. Thus
|
||||
since Django 2.1 default <code>serializers.BooleanField</code> instances will be generated
|
||||
without the <code>required</code> kwarg (i.e. equivalent to <code>required=True</code>) whereas with
|
||||
previous versions of Django, default <code>BooleanField</code> instances will be generated
|
||||
with a <code>required=False</code> option. If you want to control this behaviour manually,
|
||||
explicitly declare the <code>BooleanField</code> on the serializer class, or use the
|
||||
<code>extra_kwargs</code> option to set the <code>required</code> flag.</p>
|
||||
<p>Corresponds to <code>django.db.models.fields.BooleanField</code>.</p>
|
||||
<p><strong>Signature:</strong> <code>BooleanField()</code></p>
|
||||
<h2 id="nullbooleanfield"><a class="toclink" href="#nullbooleanfield">NullBooleanField</a></h2>
|
||||
|
|
|
@ -616,7 +616,7 @@ class UserListView(generics.ListAPIView):
|
|||
"""
|
||||
model = Product
|
||||
serializer_class = ProductSerializer
|
||||
filter_class = ProductFilter
|
||||
filterset_class = ProductFilter
|
||||
|
||||
def get_queryset(self):
|
||||
user = self.request.user
|
||||
|
@ -642,12 +642,12 @@ class UserListView(generics.ListAPIView):
|
|||
...
|
||||
filter_backends = (DjangoFilterBackend,)
|
||||
</code></pre>
|
||||
<p>If all you need is simple equality-based filtering, you can set a <code>filter_fields</code> attribute on the view, or viewset, listing the set of fields you wish to filter against.</p>
|
||||
<p>If all you need is simple equality-based filtering, you can set a <code>filterset_fields</code> attribute on the view, or viewset, listing the set of fields you wish to filter against.</p>
|
||||
<pre><code>class ProductList(generics.ListAPIView):
|
||||
queryset = Product.objects.all()
|
||||
serializer_class = ProductSerializer
|
||||
filter_backends = (DjangoFilterBackend,)
|
||||
filter_fields = ('category', 'in_stock')
|
||||
filterset_fields = ('category', 'in_stock')
|
||||
</code></pre>
|
||||
<p>This will automatically create a <code>FilterSet</code> class for the given fields, and will allow you to make requests such as:</p>
|
||||
<pre><code>http://example.com/api/products?category=clothing&in_stock=True
|
||||
|
@ -686,6 +686,12 @@ class UserListView(generics.ListAPIView):
|
|||
<pre><code>search_fields = ('=username', '=email')
|
||||
</code></pre>
|
||||
<p>By default, the search parameter is named <code>'search</code>', but this may be overridden with the <code>SEARCH_PARAM</code> setting.</p>
|
||||
<p>To dynamically change search fields based on request content, it's possible to subclass the <code>SearchFilter</code> and override the <code>get_search_fields()</code> function. For example, the following subclass will only search on <code>title</code> if the query parameter <code>title_only</code> is in the request:</p>
|
||||
<pre><code>class CustomSearchFilter(self, view, request):
|
||||
if request.query_params.get('title_only'):
|
||||
return ('title',)
|
||||
return super(CustomSearchFilter, self).get_search_fields(view, request)
|
||||
</code></pre>
|
||||
<p>For more details, see the <a href="https://docs.djangoproject.com/en/stable/ref/contrib/admin/#django.contrib.admin.ModelAdmin.search_fields">Django documentation</a>.</p>
|
||||
<hr />
|
||||
<h2 id="orderingfilter"><a class="toclink" href="#orderingfilter">OrderingFilter</a></h2>
|
||||
|
|
|
@ -726,7 +726,7 @@ that REST framework provides, by implementing a <code>get_schema_fields()</code>
|
|||
<h2 id="drf-proxy-pagination"><a class="toclink" href="#drf-proxy-pagination">drf-proxy-pagination</a></h2>
|
||||
<p>The <a href="https://github.com/tuffnatty/drf-proxy-pagination"><code>drf-proxy-pagination</code> package</a> includes a <code>ProxyPagination</code> class which allows to choose pagination class with a query parameter.</p>
|
||||
<h2 id="link-header-pagination"><a class="toclink" href="#link-header-pagination">link-header-pagination</a></h2>
|
||||
<p>The <a href="https://github.com/tbeadle/django-rest-framework-link-header-pagination"><code>django-rest-framework-link-header-pagination</code> package</a> includes a <code>LinkHeaderPagination</code> class which provides pagination via an HTTP <code>Link</code> header as desribed in <a href="../github-link-pagination">Github's developer documentation</a>.</p>
|
||||
<p>The <a href="https://github.com/tbeadle/django-rest-framework-link-header-pagination"><code>django-rest-framework-link-header-pagination</code> package</a> includes a <code>LinkHeaderPagination</code> class which provides pagination via an HTTP <code>Link</code> header as described in <a href="../github-link-pagination">Github's developer documentation</a>.</p>
|
||||
|
||||
|
||||
</div> <!--/span-->
|
||||
|
|
|
@ -484,7 +484,7 @@
|
|||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#django-rest-framework-api-key">Django Rest Framework API Key</a>
|
||||
<a href="#django-rest-framework-api-key">Django REST Framework API Key</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
@ -519,8 +519,8 @@
|
|||
</blockquote>
|
||||
<p>Together with <a href="../authentication/">authentication</a> and <a href="../throttling/">throttling</a>, permissions determine whether a request should be granted or denied access.</p>
|
||||
<p>Permission checks are always run at the very start of the view, before any other code is allowed to proceed. Permission checks will typically use the authentication information in the <code>request.user</code> and <code>request.auth</code> properties to determine if the incoming request should be permitted.</p>
|
||||
<p>Permissions are used to grant or deny access different classes of users to different parts of the API.</p>
|
||||
<p>The simplest style of permission would be to allow access to any authenticated user, and deny access to any unauthenticated user. This corresponds the <code>IsAuthenticated</code> class in REST framework.</p>
|
||||
<p>Permissions are used to grant or deny access for different classes of users to different parts of the API.</p>
|
||||
<p>The simplest style of permission would be to allow access to any authenticated user, and deny access to any unauthenticated user. This corresponds to the <code>IsAuthenticated</code> class in REST framework.</p>
|
||||
<p>A slightly less strict style of permission would be to allow full access to authenticated users, but allow read-only access to unauthenticated users. This corresponds to the <code>IsAuthenticatedOrReadOnly</code> class in REST framework.</p>
|
||||
<h2 id="how-permissions-are-determined"><a class="toclink" href="#how-permissions-are-determined">How permissions are determined</a></h2>
|
||||
<p>Permissions in REST framework are always defined as a list of permission classes.</p>
|
||||
|
@ -545,6 +545,15 @@ or if you override the <code>get_object</code> method on a generic view, then yo
|
|||
self.check_object_permissions(self.request, obj)
|
||||
return obj
|
||||
</code></pre>
|
||||
<hr />
|
||||
<p><strong>Note</strong>: With the exception of <code>DjangoObjectPermissions</code>, the provided
|
||||
permission classes in <code>rest_framework.permssions</code> <strong>do not</strong> implement the
|
||||
methods necessary to check object permissions.</p>
|
||||
<p>If you wish to use the provided permission classes in order to check object
|
||||
permissions, <strong>you must</strong> subclass them and implement the
|
||||
<code>has_object_permission()</code> method described in the <a href="#custom-permissions"><em>Custom
|
||||
permissions</em></a> section (below).</p>
|
||||
<hr />
|
||||
<h4 id="limitations-of-object-level-permissions"><a class="toclink" href="#limitations-of-object-level-permissions">Limitations of object level permissions</a></h4>
|
||||
<p>For performance reasons the generic views will not automatically apply object level permissions to each instance in a queryset when returning a list of objects.</p>
|
||||
<p>Often when you're using object level permissions you'll also want to <a href="../filtering/">filter the queryset</a> appropriately, to ensure that users only have visibility onto instances that they are permitted to view.</p>
|
||||
|
@ -608,7 +617,7 @@ class ExampleView(APIView):
|
|||
}
|
||||
return Response(content)
|
||||
</code></pre>
|
||||
<p><strong>Note:</strong> it only supports & -and- and | -or-.</p>
|
||||
<p><strong>Note:</strong> it supports & (and), | (or) and ~ (not).</p>
|
||||
<hr />
|
||||
<h1 id="api-reference"><a class="toclink" href="#api-reference">API Reference</a></h1>
|
||||
<h2 id="allowany"><a class="toclink" href="#allowany">AllowAny</a></h2>
|
||||
|
@ -719,8 +728,8 @@ class BlacklistPermission(permissions.BasePermission):
|
|||
<p>The <a href="https://github.com/Helioscene/dry-rest-permissions">DRY Rest Permissions</a> package provides the ability to define different permissions for individual default and custom actions. This package is made for apps with permissions that are derived from relationships defined in the app's data model. It also supports permission checks being returned to a client app through the API's serializer. Additionally it supports adding permissions to the default and custom list actions to restrict the data they retrieve per user.</p>
|
||||
<h2 id="django-rest-framework-roles"><a class="toclink" href="#django-rest-framework-roles">Django Rest Framework Roles</a></h2>
|
||||
<p>The <a href="https://github.com/computer-lab/django-rest-framework-roles">Django Rest Framework Roles</a> package makes it easier to parameterize your API over multiple types of users.</p>
|
||||
<h2 id="django-rest-framework-api-key"><a class="toclink" href="#django-rest-framework-api-key">Django Rest Framework API Key</a></h2>
|
||||
<p>The <a href="https://github.com/manosim/django-rest-framework-api-key">Django Rest Framework API Key</a> package allows you to ensure that every request made to the server requires an API key header. You can generate one from the django admin interface.</p>
|
||||
<h2 id="django-rest-framework-api-key"><a class="toclink" href="#django-rest-framework-api-key">Django REST Framework API Key</a></h2>
|
||||
<p>The <a href="https://github.com/florimondmanca/djangorestframework-api-key">Django REST Framework API Key</a> package provides the ability to authorize clients based on customizable API key headers. This package is targeted at situations in which regular user-based authentication (e.g. <code>TokenAuthentication</code>) is not suitable, e.g. allowing non-human clients to safely use your API. API keys are generated and validated through cryptographic methods and can be created and revoked from the Django admin interface at anytime.</p>
|
||||
<h2 id="django-rest-framework-role-filters"><a class="toclink" href="#django-rest-framework-role-filters">Django Rest Framework Role Filters</a></h2>
|
||||
<p>The <a href="https://github.com/allisson/django-rest-framework-role-filters">Django Rest Framework Role Filters</a> package provides simple filtering over multiple types of roles.</p>
|
||||
|
||||
|
|
|
@ -570,11 +570,11 @@ class Track(models.Model):
|
|||
unique_together = ('album', 'order')
|
||||
ordering = ['order']
|
||||
|
||||
def __unicode__(self):
|
||||
def __str__(self):
|
||||
return '%d: %s' % (self.order, self.title)
|
||||
</code></pre>
|
||||
<h2 id="stringrelatedfield"><a class="toclink" href="#stringrelatedfield">StringRelatedField</a></h2>
|
||||
<p><code>StringRelatedField</code> may be used to represent the target of the relationship using its <code>__unicode__</code> method.</p>
|
||||
<p><code>StringRelatedField</code> may be used to represent the target of the relationship using its <code>__str__</code> method.</p>
|
||||
<p>For example, the following serializer.</p>
|
||||
<pre><code>class AlbumSerializer(serializers.ModelSerializer):
|
||||
tracks = serializers.StringRelatedField(many=True)
|
||||
|
@ -945,7 +945,7 @@ class CustomerHyperlink(serializers.HyperlinkedRelatedField):
|
|||
object_id = models.PositiveIntegerField()
|
||||
tagged_object = GenericForeignKey('content_type', 'object_id')
|
||||
|
||||
def __unicode__(self):
|
||||
def __str__(self):
|
||||
return self.tag_name
|
||||
</code></pre>
|
||||
<p>And the following two models, which may have associated tags:</p>
|
||||
|
|
|
@ -530,7 +530,7 @@
|
|||
<h1 id="content-negotiation"><a class="toclink" href="#content-negotiation">Content negotiation</a></h1>
|
||||
<p>The request exposes some properties that allow you to determine the result of the content negotiation stage. This allows you to implement behaviour such as selecting a different serialisation schemes for different media types.</p>
|
||||
<h2 id="accepted_renderer"><a class="toclink" href="#accepted_renderer">.accepted_renderer</a></h2>
|
||||
<p>The renderer instance what was selected by the content negotiation stage.</p>
|
||||
<p>The renderer instance that was selected by the content negotiation stage.</p>
|
||||
<h2 id="accepted_media_type"><a class="toclink" href="#accepted_media_type">.accepted_media_type</a></h2>
|
||||
<p>A string representing the media type that was accepted by the content negotiation stage.</p>
|
||||
<hr />
|
||||
|
|
|
@ -760,7 +760,7 @@ serializer = CommentSerializer(comment, data=data)
|
|||
serializer.is_valid()
|
||||
# False
|
||||
serializer.errors
|
||||
# {'email': [u'Enter a valid e-mail address.'], 'created': [u'This field is required.']}
|
||||
# {'email': ['Enter a valid e-mail address.'], 'created': ['This field is required.']}
|
||||
</code></pre>
|
||||
<p>Each key in the dictionary will be the field name, and the values will be lists of strings of any error messages corresponding to that field. The <code>non_field_errors</code> key may also be present, and will list any general validation errors. The name of the <code>non_field_errors</code> key may be customized using the <code>NON_FIELD_ERRORS_KEY</code> REST framework setting.</p>
|
||||
<p>When deserializing a list of items, errors will be returned as a list of dictionaries representing each of the deserialized items.</p>
|
||||
|
@ -838,7 +838,7 @@ class GameRecord(serializers.Serializer):
|
|||
<h2 id="partial-updates"><a class="toclink" href="#partial-updates">Partial updates</a></h2>
|
||||
<p>By default, serializers must be passed values for all required fields or they will raise validation errors. You can use the <code>partial</code> argument in order to allow partial updates.</p>
|
||||
<pre><code># Update `comment` with partial data
|
||||
serializer = CommentSerializer(comment, data={'content': u'foo bar'}, partial=True)
|
||||
serializer = CommentSerializer(comment, data={'content': 'foo bar'}, partial=True)
|
||||
</code></pre>
|
||||
<h2 id="dealing-with-nested-objects"><a class="toclink" href="#dealing-with-nested-objects">Dealing with nested objects</a></h2>
|
||||
<p>The previous examples are fine for dealing with objects that only have simple datatypes, but sometimes we also need to be able to represent more complex objects, where some of the attributes of an object might not be simple datatypes such as strings, dates or integers.</p>
|
||||
|
@ -871,7 +871,7 @@ class CommentSerializer(serializers.Serializer):
|
|||
serializer.is_valid()
|
||||
# False
|
||||
serializer.errors
|
||||
# {'user': {'email': [u'Enter a valid e-mail address.']}, 'created': [u'This field is required.']}
|
||||
# {'user': {'email': ['Enter a valid e-mail address.']}, 'created': ['This field is required.']}
|
||||
</code></pre>
|
||||
<p>Similarly, the <code>.validated_data</code> property will include nested data structures.</p>
|
||||
<h4 id="writing-create-methods-for-nested-representations"><a class="toclink" href="#writing-create-methods-for-nested-representations">Writing <code>.create()</code> methods for nested representations</a></h4>
|
||||
|
@ -971,7 +971,7 @@ serializer.data
|
|||
<p>You can provide arbitrary additional context by passing a <code>context</code> argument when instantiating the serializer. For example:</p>
|
||||
<pre><code>serializer = AccountSerializer(account, context={'request': request})
|
||||
serializer.data
|
||||
# {'id': 6, 'owner': u'denvercoder9', 'created': datetime.datetime(2013, 2, 12, 09, 44, 56, 678870), 'details': 'http://example.com/accounts/6/details'}
|
||||
# {'id': 6, 'owner': 'denvercoder9', 'created': datetime.datetime(2013, 2, 12, 09, 44, 56, 678870), 'details': 'http://example.com/accounts/6/details'}
|
||||
</code></pre>
|
||||
<p>The context dictionary can be used within any serializer field logic, such as a custom <code>.to_representation()</code> method, by accessing the <code>self.context</code> attribute.</p>
|
||||
<hr />
|
||||
|
@ -1485,10 +1485,10 @@ class MySerializer(MyBaseSerializer):
|
|||
>>> model = User
|
||||
>>> fields = ('id', 'username', 'email')
|
||||
>>>
|
||||
>>> print UserSerializer(user)
|
||||
>>> print(UserSerializer(user))
|
||||
{'id': 2, 'username': 'jonwatts', 'email': 'jon@example.com'}
|
||||
>>>
|
||||
>>> print UserSerializer(user, fields=('id', 'email'))
|
||||
>>> print(UserSerializer(user, fields=('id', 'email')))
|
||||
{'id': 2, 'email': 'jon@example.com'}
|
||||
</code></pre>
|
||||
<h2 id="customizing-the-default-fields"><a class="toclink" href="#customizing-the-default-fields">Customizing the default fields</a></h2>
|
||||
|
|
|
@ -530,8 +530,10 @@ def example_view(request, format=None):
|
|||
<h2 id="setting-up-the-cache"><a class="toclink" href="#setting-up-the-cache">Setting up the cache</a></h2>
|
||||
<p>The throttle classes provided by REST framework use Django's cache backend. You should make sure that you've set appropriate <a href="https://docs.djangoproject.com/en/stable/ref/settings/#caches">cache settings</a>. The default value of <code>LocMemCache</code> backend should be okay for simple setups. See Django's <a href="https://docs.djangoproject.com/en/stable/topics/cache/#setting-up-the-cache">cache documentation</a> for more details.</p>
|
||||
<p>If you need to use a cache other than <code>'default'</code>, you can do so by creating a custom throttle class and setting the <code>cache</code> attribute. For example:</p>
|
||||
<pre><code>class CustomAnonRateThrottle(AnonRateThrottle):
|
||||
cache = get_cache('alternate')
|
||||
<pre><code>from django.core.cache import caches
|
||||
|
||||
class CustomAnonRateThrottle(AnonRateThrottle):
|
||||
cache = caches['alternate']
|
||||
</code></pre>
|
||||
<p>You'll need to remember to also set your custom throttle class in the <code>'DEFAULT_THROTTLE_CLASSES'</code> settings key, or using the <code>throttle_classes</code> view attribute.</p>
|
||||
<hr />
|
||||
|
|
|
@ -763,7 +763,7 @@ LocationRatingSerializer():
|
|||
</code></pre>
|
||||
<p>These fields will be mapped to <code>serializers.ReadOnlyField()</code> instances.</p>
|
||||
<pre><code>>>> serializer = InvitationSerializer()
|
||||
>>> print repr(serializer)
|
||||
>>> print(repr(serializer))
|
||||
InvitationSerializer():
|
||||
to_email = EmailField(max_length=75)
|
||||
message = CharField(max_length=1000)
|
||||
|
|
|
@ -486,10 +486,10 @@
|
|||
<p>The timeline for deprecation of a feature present in version 1.0 would work as follows:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<p>Version 1.1 would remain <strong>fully backwards compatible</strong> with 1.0, but would raise <code>PendingDeprecationWarning</code> warnings if you use the feature that are due to be deprecated. These warnings are <strong>silent by default</strong>, but can be explicitly enabled when you're ready to start migrating any required changes. For example if you start running your tests using <code>python -Wd manage.py test</code>, you'll be warned of any API changes you need to make.</p>
|
||||
<p>Version 1.1 would remain <strong>fully backwards compatible</strong> with 1.0, but would raise <code>RemovedInDRF13Warning</code> warnings, subclassing <code>PendingDeprecationWarning</code>, if you use the feature that are due to be deprecated. These warnings are <strong>silent by default</strong>, but can be explicitly enabled when you're ready to start migrating any required changes. For example if you start running your tests using <code>python -Wd manage.py test</code>, you'll be warned of any API changes you need to make.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Version 1.2 would escalate these warnings to <code>DeprecationWarning</code>, which is loud by default.</p>
|
||||
<p>Version 1.2 would escalate these warnings to subclass <code>DeprecationWarning</code>, which is loud by default.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Version 1.3 would remove the deprecated bits of API entirely.</p>
|
||||
|
@ -505,8 +505,27 @@
|
|||
</code></pre>
|
||||
<hr />
|
||||
<h2 id="39x-series"><a class="toclink" href="#39x-series">3.9.x series</a></h2>
|
||||
<h3 id="392"><a class="toclink" href="#392">3.9.2</a></h3>
|
||||
<p><strong>Date</strong>: <a href="https://github.com/encode/django-rest-framework/milestone/71?closed=1">3rd March 2019</a></p>
|
||||
<ul>
|
||||
<li>Routers: invalidate <code>_urls</code> cache on <code>register()</code> <a href="https://github.com/encode/django-rest-framework/issues/6407">#6407</a></li>
|
||||
<li>Deferred schema renderer creation to avoid requiring pyyaml. <a href="https://github.com/encode/django-rest-framework/issues/6416">#6416</a></li>
|
||||
<li>Added 'request_forms' block to base.html <a href="https://github.com/encode/django-rest-framework/issues/6340">#6340</a></li>
|
||||
<li>Fixed SchemaView to reset renderer on exception. <a href="https://github.com/encode/django-rest-framework/issues/6429">#6429</a></li>
|
||||
<li>Update Django Guardian dependency. <a href="https://github.com/encode/django-rest-framework/issues/6430">#6430</a></li>
|
||||
<li>Ensured support for Django 2.2 <a href="https://github.com/encode/django-rest-framework/issues/6422">#6422</a> & <a href="https://github.com/encode/django-rest-framework/issues/6455">#6455</a></li>
|
||||
<li>Made templates compatible with session-based CSRF. <a href="https://github.com/encode/django-rest-framework/issues/6207">#6207</a></li>
|
||||
<li>Adjusted field <code>validators</code> to accept non-list iterables. <a href="https://github.com/encode/django-rest-framework/issues/6282">#6282</a></li>
|
||||
<li>Added SearchFilter.get_search_fields() hook. <a href="https://github.com/encode/django-rest-framework/issues/6279">#6279</a></li>
|
||||
<li>Fix DeprecationWarning when accessing collections.abc classes via collections <a href="https://github.com/encode/django-rest-framework/issues/6268">#6268</a></li>
|
||||
<li>Allowed Q objects in limit_choices_to introspection. <a href="https://github.com/encode/django-rest-framework/issues/6472">#6472</a></li>
|
||||
<li>Added lazy evaluation to composed permissions. <a href="https://github.com/encode/django-rest-framework/issues/6463">#6463</a></li>
|
||||
<li>Add negation ~ operator to permissions composition <a href="https://github.com/encode/django-rest-framework/issues/6361">#6361</a></li>
|
||||
<li>Avoided calling distinct on annotated fields in SearchFilter. <a href="https://github.com/encode/django-rest-framework/issues/6240">#6240</a></li>
|
||||
<li>Introduced <code>RemovedInDRF…Warning</code> classes to simplify deprecations. <a href="https://github.com/encode/django-rest-framework/issues/6480">#6480</a></li>
|
||||
</ul>
|
||||
<h3 id="391"><a class="toclink" href="#391">3.9.1</a></h3>
|
||||
<p><strong>Date</strong>: <a href="https://github.com/encode/django-rest-framework/milestone/70?closed=1">16th Janurary 2019</a></p>
|
||||
<p><strong>Date</strong>: <a href="https://github.com/encode/django-rest-framework/milestone/71?closed=1">16th Janurary 2019</a></p>
|
||||
<ul>
|
||||
<li>Resolve XSS issue in browsable API. <a href="https://github.com/encode/django-rest-framework/issues/6330">#6330</a></li>
|
||||
<li>Upgrade Bootstrap to 3.4.0 to resolve XSS issue.</li>
|
||||
|
@ -1557,6 +1576,8 @@ Previously may have been stored internally as <code>None</code>.</p>
|
|||
<!-- 3.9.0 -->
|
||||
|
||||
<!-- 3.9.1 -->
|
||||
|
||||
<!-- 3.9.2 -->
|
||||
|
||||
|
||||
</div> <!--/span-->
|
||||
|
|
0
css/bootstrap-responsive.css
vendored
Executable file → Normal file
0
css/bootstrap-responsive.css
vendored
Executable file → Normal file
0
css/bootstrap.css
vendored
Executable file → Normal file
0
css/bootstrap.css
vendored
Executable file → Normal file
|
@ -553,7 +553,7 @@ continued development by <strong><a href="community/funding/">signing up for a p
|
|||
<p>REST framework requires the following:</p>
|
||||
<ul>
|
||||
<li>Python (2.7, 3.4, 3.5, 3.6, 3.7)</li>
|
||||
<li>Django (1.11, 2.0, 2.1)</li>
|
||||
<li>Django (1.11, 2.0, 2.1, 2.2)</li>
|
||||
</ul>
|
||||
<p>We <strong>highly recommend</strong> and only officially support the latest patch release of
|
||||
each Python and Django series.</p>
|
||||
|
|
0
js/bootstrap-2.1.1-min.js
vendored
Executable file → Normal file
0
js/bootstrap-2.1.1-min.js
vendored
Executable file → Normal file
File diff suppressed because one or more lines are too long
128
sitemap.xml
128
sitemap.xml
|
@ -4,7 +4,7 @@
|
|||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
|
@ -13,49 +13,49 @@
|
|||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//tutorial/quickstart/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//tutorial/1-serialization/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//tutorial/2-requests-and-responses/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//tutorial/3-class-based-views/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//tutorial/4-authentication-and-permissions/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//tutorial/5-relationships-and-hyperlinked-apis/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//tutorial/6-viewsets-and-routers/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//tutorial/7-schemas-and-client-libraries/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
|
@ -65,169 +65,169 @@
|
|||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//api-guide/requests/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//api-guide/responses/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//api-guide/views/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//api-guide/generic-views/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//api-guide/viewsets/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//api-guide/routers/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//api-guide/parsers/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//api-guide/renderers/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//api-guide/serializers/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//api-guide/fields/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//api-guide/relations/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//api-guide/validators/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//api-guide/authentication/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//api-guide/permissions/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//api-guide/caching/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//api-guide/throttling/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//api-guide/filtering/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//api-guide/pagination/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//api-guide/versioning/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//api-guide/content-negotiation/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//api-guide/metadata/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//api-guide/schemas/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//api-guide/format-suffixes/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//api-guide/reverse/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//api-guide/exceptions/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//api-guide/status-codes/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//api-guide/testing/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//api-guide/settings/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
|
@ -237,49 +237,49 @@
|
|||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//topics/documenting-your-api/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//topics/api-clients/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//topics/internationalization/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//topics/ajax-csrf-cors/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//topics/html-and-forms/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//topics/browser-enhancements/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//topics/browsable-api/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//topics/rest-hypermedia-hateoas/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
|
@ -289,115 +289,115 @@
|
|||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//community/tutorials-and-resources/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//community/third-party-packages/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//community/contributing/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//community/project-management/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//community/release-notes/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//community/3.9-announcement/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//community/3.8-announcement/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//community/3.7-announcement/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//community/3.6-announcement/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//community/3.5-announcement/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//community/3.4-announcement/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//community/3.3-announcement/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//community/3.2-announcement/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//community/3.1-announcement/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//community/3.0-announcement/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//community/kickstarter-announcement/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//community/mozilla-grant/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//community/funding/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://www.django-rest-framework.org//community/jobs/</loc>
|
||||
<lastmod>2019-01-16</lastmod>
|
||||
<lastmod>2019-03-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
||||
|
|
|
@ -450,9 +450,9 @@
|
|||
<p>— <a href="https://www.amazon.com/RESTful-Web-Services-Leonard-Richardson/dp/0596529260">RESTful Web Services</a>, Leonard Richardson & Sam Ruby.</p>
|
||||
</blockquote>
|
||||
<p>In order to allow the browsable API to function, there are a couple of browser enhancements that REST framework needs to provide.</p>
|
||||
<p>As of version 3.3.0 onwards these are enabled with javascript, using the <a href="https://github.com/encode/ajax-form">ajax-form</a> library.</p>
|
||||
<p>As of version 3.3.0 onwards these are enabled with javascript, using the <a href="https://github.com/tomchristie/ajax-form">ajax-form</a> library.</p>
|
||||
<h2 id="browser-based-put-delete-etc"><a class="toclink" href="#browser-based-put-delete-etc">Browser based PUT, DELETE, etc...</a></h2>
|
||||
<p>The <a href="https://github.com/encode/ajax-form">AJAX form library</a> supports browser-based <code>PUT</code>, <code>DELETE</code> and other methods on HTML forms.</p>
|
||||
<p>The <a href="https://github.com/tomchristie/ajax-form">AJAX form library</a> supports browser-based <code>PUT</code>, <code>DELETE</code> and other methods on HTML forms.</p>
|
||||
<p>After including the library, use the <code>data-method</code> attribute on the form, like so:</p>
|
||||
<pre><code><form action="/" data-method="PUT">
|
||||
<input name='foo'/>
|
||||
|
@ -461,7 +461,7 @@
|
|||
</code></pre>
|
||||
<p>Note that prior to 3.3.0, this support was server-side rather than javascript based. The method overloading style (as used in <a href="https://guides.rubyonrails.org/form_helpers.html#how-do-forms-with-put-or-delete-methods-work">Ruby on Rails</a>) is no longer supported due to subtle issues that it introduces in request parsing.</p>
|
||||
<h2 id="browser-based-submission-of-non-form-content"><a class="toclink" href="#browser-based-submission-of-non-form-content">Browser based submission of non-form content</a></h2>
|
||||
<p>Browser-based submission of content types such as JSON are supported by the <a href="https://github.com/encode/ajax-form">AJAX form library</a>, using form fields with <code>data-override='content-type'</code> and <code>data-override='content'</code> attributes.</p>
|
||||
<p>Browser-based submission of content types such as JSON are supported by the <a href="https://github.com/tomchristie/ajax-form">AJAX form library</a>, using form fields with <code>data-override='content-type'</code> and <code>data-override='content'</code> attributes.</p>
|
||||
<p>For example:</p>
|
||||
<pre><code> <form action="/">
|
||||
<input data-override='content-type' value='application/json' type='hidden'/>
|
||||
|
|
|
@ -571,18 +571,18 @@ from rest_framework.parsers import JSONParser
|
|||
snippet = Snippet(code='foo = "bar"\n')
|
||||
snippet.save()
|
||||
|
||||
snippet = Snippet(code='print "hello, world"\n')
|
||||
snippet = Snippet(code='print("hello, world")\n')
|
||||
snippet.save()
|
||||
</code></pre>
|
||||
<p>We've now got a few snippet instances to play with. Let's take a look at serializing one of those instances.</p>
|
||||
<pre><code>serializer = SnippetSerializer(snippet)
|
||||
serializer.data
|
||||
# {'id': 2, 'title': u'', 'code': u'print "hello, world"\n', 'linenos': False, 'language': u'python', 'style': u'friendly'}
|
||||
# {'id': 2, 'title': '', 'code': 'print("hello, world")\n', 'linenos': False, 'language': 'python', 'style': 'friendly'}
|
||||
</code></pre>
|
||||
<p>At this point we've translated the model instance into Python native datatypes. To finalize the serialization process we render the data into <code>json</code>.</p>
|
||||
<pre><code>content = JSONRenderer().render(serializer.data)
|
||||
content
|
||||
# '{"id": 2, "title": "", "code": "print \\"hello, world\\"\\n", "linenos": false, "language": "python", "style": "friendly"}'
|
||||
# '{"id": 2, "title": "", "code": "print(\\"hello, world\\")\\n", "linenos": false, "language": "python", "style": "friendly"}'
|
||||
</code></pre>
|
||||
<p>Deserialization is similar. First we parse a stream into Python native datatypes...</p>
|
||||
<pre><code>import io
|
||||
|
@ -595,7 +595,7 @@ data = JSONParser().parse(stream)
|
|||
serializer.is_valid()
|
||||
# True
|
||||
serializer.validated_data
|
||||
# OrderedDict([('title', ''), ('code', 'print "hello, world"\n'), ('linenos', False), ('language', 'python'), ('style', 'friendly')])
|
||||
# OrderedDict([('title', ''), ('code', 'print("hello, world")\n'), ('linenos', False), ('language', 'python'), ('style', 'friendly')])
|
||||
serializer.save()
|
||||
# <Snippet: Snippet object>
|
||||
</code></pre>
|
||||
|
@ -603,7 +603,7 @@ serializer.save()
|
|||
<p>We can also serialize querysets instead of model instances. To do so we simply add a <code>many=True</code> flag to the serializer arguments.</p>
|
||||
<pre><code>serializer = SnippetSerializer(Snippet.objects.all(), many=True)
|
||||
serializer.data
|
||||
# [OrderedDict([('id', 1), ('title', u''), ('code', u'foo = "bar"\n'), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('id', 2), ('title', u''), ('code', u'print "hello, world"\n'), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('id', 3), ('title', u''), ('code', u'print "hello, world"'), ('linenos', False), ('language', 'python'), ('style', 'friendly')])]
|
||||
# [OrderedDict([('id', 1), ('title', ''), ('code', 'foo = "bar"\n'), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('id', 2), ('title', ''), ('code', 'print("hello, world")\n'), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('id', 3), ('title', ''), ('code', 'print("hello, world")'), ('linenos', False), ('language', 'python'), ('style', 'friendly')])]
|
||||
</code></pre>
|
||||
<h2 id="using-modelserializers"><a class="toclink" href="#using-modelserializers">Using ModelSerializers</a></h2>
|
||||
<p>Our <code>SnippetSerializer</code> class is replicating a lot of information that's also contained in the <code>Snippet</code> model. It would be nice if we could keep our code a bit more concise.</p>
|
||||
|
@ -744,7 +744,7 @@ HTTP/1.1 200 OK
|
|||
{
|
||||
"id": 2,
|
||||
"title": "",
|
||||
"code": "print \"hello, world\"\n",
|
||||
"code": "print(\"hello, world\")\n",
|
||||
"linenos": false,
|
||||
"language": "python",
|
||||
"style": "friendly"
|
||||
|
@ -759,7 +759,7 @@ HTTP/1.1 200 OK
|
|||
{
|
||||
"id": 2,
|
||||
"title": "",
|
||||
"code": "print \"hello, world\"\n",
|
||||
"code": "print(\"hello, world\")\n",
|
||||
"linenos": false,
|
||||
"language": "python",
|
||||
"style": "friendly"
|
||||
|
|
|
@ -570,7 +570,7 @@ HTTP/1.1 200 OK
|
|||
{
|
||||
"id": 2,
|
||||
"title": "",
|
||||
"code": "print \"hello, world\"\n",
|
||||
"code": "print(\"hello, world\")\n",
|
||||
"linenos": false,
|
||||
"language": "python",
|
||||
"style": "friendly"
|
||||
|
@ -587,24 +587,24 @@ http http://127.0.0.1:8000/snippets.api # Browsable API suffix
|
|||
</code></pre>
|
||||
<p>Similarly, we can control the format of the request that we send, using the <code>Content-Type</code> header.</p>
|
||||
<pre><code># POST using form data
|
||||
http --form POST http://127.0.0.1:8000/snippets/ code="print 123"
|
||||
http --form POST http://127.0.0.1:8000/snippets/ code="print(123)"
|
||||
|
||||
{
|
||||
"id": 3,
|
||||
"title": "",
|
||||
"code": "print 123",
|
||||
"code": "print(123)",
|
||||
"linenos": false,
|
||||
"language": "python",
|
||||
"style": "friendly"
|
||||
}
|
||||
|
||||
# POST using JSON
|
||||
http --json POST http://127.0.0.1:8000/snippets/ code="print 456"
|
||||
http --json POST http://127.0.0.1:8000/snippets/ code="print(456)"
|
||||
|
||||
{
|
||||
"id": 4,
|
||||
"title": "",
|
||||
"code": "print 456",
|
||||
"code": "print(456)",
|
||||
"linenos": false,
|
||||
"language": "python",
|
||||
"style": "friendly"
|
||||
|
|
|
@ -465,8 +465,9 @@ format.</p>
|
|||
automatically generated schemas. Since we're using viewsets and routers,
|
||||
we can simply use the automatic schema generation.</p>
|
||||
<p>You'll need to install the <code>coreapi</code> python package in order to include an
|
||||
API schema.</p>
|
||||
<pre><code>$ pip install coreapi
|
||||
API schema, and <code>pyyaml</code> to render the schema into the commonly used
|
||||
YAML-based OpenAPI format.</p>
|
||||
<pre><code>$ pip install coreapi pyyaml
|
||||
</code></pre>
|
||||
<p>We can now include a schema for our API, by including an autogenerated schema
|
||||
view in our URL configuration.</p>
|
||||
|
|
Loading…
Reference in New Issue
Block a user