@@ -664,7 +668,7 @@ for user in User.objects.all():
When using TokenAuthentication, 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 obtain_auth_token view to your URLconf:
If you want to create a custom field, you'll need to subclass Field and then override either one or both of the .to_representation() and .to_internal_value() methods. These two methods are used to convert between the initial datatype, and a primitive, serializable datatype. Primitive datatypes will typically be any of a number, string, boolean, date/time/datetime or None. They may also be any list or dictionary like object that only contains other primitive objects. Other types might be supported, depending on the renderer that you are using.
The .to_representation() method is called to convert the initial datatype into a primitive, serializable datatype.
-
The to_internal_value() method is called to restore a primitive datatype into its internal python representation. This method should raise a serializers.ValidationError if the data is invalid.
+
The .to_internal_value() method is called to restore a primitive datatype into its internal python representation. This method should raise a serializers.ValidationError if the data is invalid.
@@ -575,7 +579,7 @@ class UserList(generics.ListCreateAPIView):
return Response(serializer.data)
For very simple cases you might want to pass through any class attributes using the .as_view() method. For example, your URLconf might include something like the following entry:
The following is an example of a permission class that checks the incoming request's IP address against a blacklist, and denies the request if the IP has been blacklisted.
+
The following is an example of a permission class that checks the incoming request's IP address against a blocklist, and denies the request if the IP has been blocked.
from rest_framework import permissions
-class BlacklistPermission(permissions.BasePermission):
+class BlocklistPermission(permissions.BasePermission):
"""
- Global permission check for blacklisted IPs.
+ Global permission check for blocked IPs.
"""
def has_permission(self, request, view):
ip_addr = request.META['REMOTE_ADDR']
- blacklisted = Blacklist.objects.filter(ip_addr=ip_addr).exists()
- return not blacklisted
+ blocked = Blocklist.objects.filter(ip_addr=ip_addr).exists()
+ return not blocked
As well as global permissions, that are run against all incoming requests, you can also create object-level permissions, that are only run against operations that affect a particular object instance. For example:
class IsOwnerOrReadOnly(permissions.BasePermission):
@@ -731,13 +739,15 @@ class BlacklistPermission(permissions.BasePermission):
The REST Condition package is another extension for building complex permissions in a simple and convenient way. The extension allows you to combine permissions with logical operators.
The DRY Rest Permissions 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.
+
The DRY Rest Permissions 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.
The Django REST Framework API Key package provides permissions classes, models and helpers to add API key authorization to your API. It can be used to authorize internal or third-party backends and services (i.e. machines) which do not have a user account. API keys are stored securely using Django's password hashing infrastructure, and they can be viewed, edited and revoked at anytime in the Django admin.
The Django Rest Framework PSQ package is an extension that gives support for having action-based permission_classes, serializer_class, and queryset dependent on permission-based rules.
StringRelatedField may be used to represent the target of the relationship using its __str__ method.
-
For example, the following serializer.
+
For example, the following serializer:
class AlbumSerializer(serializers.ModelSerializer):
tracks = serializers.StringRelatedField(many=True)
@@ -583,7 +587,7 @@ class Track(models.Model):
model = Album
fields = ['album_name', 'artist', 'tracks']
-
Would serialize to the following representation.
+
Would serialize to the following representation:
{
'album_name': 'Things We Lost In The Fire',
'artist': 'Low',
@@ -773,7 +777,7 @@ class AlbumSerializer(serializers.ModelSerializer):
}
By default nested serializers are read-only. If you want to support write-operations to a nested serializer field you'll need to create create() and/or update() methods in order to explicitly specify how the child relationships should be saved.
+
By default nested serializers are read-only. If you want to support write-operations to a nested serializer field you'll need to create create() and/or update() methods in order to explicitly specify how the child relationships should be saved:
class TrackSerializer(serializers.ModelSerializer):
class Meta:
model = Track
@@ -817,7 +821,7 @@ output representation should be generated from the model instance.
If you want to implement a read-write relational field, you must also implement the .to_internal_value(self, data) method.
To provide a dynamic queryset based on the context, you can also override .get_queryset(self) instead of specifying .queryset on the class or when initializing the field.
For example, we could define a relational field to serialize a track to a custom string representation, using its ordering, title, and duration.
+
For example, we could define a relational field to serialize a track to a custom string representation, using its ordering, title, and duration:
import time
class TrackListingField(serializers.RelatedField):
@@ -832,7 +836,7 @@ class AlbumSerializer(serializers.ModelSerializer):
model = Album
fields = ['album_name', 'artist', 'tracks']
-
This custom field would then serialize to the following representation.
+
This custom field would then serialize to the following representation:
{
'album_name': 'Sometimes I Wish We Were an Eagle',
'artist': 'Bill Callahan',
@@ -966,7 +970,7 @@ class Note(models.Model):
text = models.CharField(max_length=1000)
tags = GenericRelation(TaggedItem)
-
We could define a custom field that could be used to serialize tagged instances, using the type of each instance to determine how it should be serialized.
+
We could define a custom field that could be used to serialize tagged instances, using the type of each instance to determine how it should be serialized:
class TaggedObjectRelatedField(serializers.RelatedField):
"""
A custom field to use for the `tagged_object` generic relationship.
diff --git a/api-guide/renderers/index.html b/api-guide/renderers/index.html
index 3225b277f..1b2f9fffb 100644
--- a/api-guide/renderers/index.html
+++ b/api-guide/renderers/index.html
@@ -293,6 +293,10 @@
Release Notes
+
Comma-separated values are a plain-text tabular data format, that can be easily imported into spreadsheet applications. Mjumbe Poe maintains the djangorestframework-csv package which provides CSV renderer support for REST framework.
UltraJSON is an optimized C JSON encoder which can give significantly faster JSON rendering. Jacob Haslehurst maintains the drf-ujson-renderer package which implements JSON rendering using the UJSON package.
+
UltraJSON is an optimized C JSON encoder which can give significantly faster JSON rendering. Adam Mertz maintains drf_ujson2, a fork of the now unmaintained drf-ujson-renderer, which implements JSON rendering using the UJSON package.
djangorestframework-camel-case provides camel case JSON renderers and parsers for REST framework. This allows serializers to use Python-style underscored field names, but be exposed in the API as Javascript-style camel case field names. It is maintained by Vitaly Babiy.
Schema generation has several moving parts. It's worth having an overview:
+
+
SchemaGenerator is a top-level class that is responsible for walking your
+ configured URL patterns, finding APIView subclasses, enquiring for their
+ schema representation, and compiling the final schema object.
+
AutoSchema encapsulates all the details necessary for per-view schema
+ introspection. Is attached to each view via the schema attribute. You
+ subclass AutoSchema in order to customize your schema.
+
The generateschema management command allows you to generate a static schema
+ offline.
+
Alternatively, you can route SchemaView to dynamically generate and serve
+ your schema.
+
settings.DEFAULT_SCHEMA_CLASS allows you to specify an AutoSchema
+ subclass to serve as your project's default.
In order to customize the top-level schema subclass
-rest_framework.schemas.openapi.SchemaGenerator and provide it as an argument
-to the generateschema command or get_schema_view() helper function.
In order to customize the top-level schema, subclass
+rest_framework.schemas.openapi.SchemaGenerator and provide your subclass
+as an argument to the generateschema command or get_schema_view() helper
+function.
from rest_framework.schemas.openapi import AutoSchema
+
+
By default, view introspection is performed by an AutoSchema instance
-accessible via the schema attribute on APIView. This provides the
-appropriate Open API operation object for the view,
-request method and path:
-
auto_schema = view.schema
+accessible via the schema attribute on APIView.
+
auto_schema = some_view.schema
+
+
AutoSchema provides the OpenAPI elements needed for each view, request method
+and path:
+
+
A list of OpenAPI components. In DRF terms these are
+ mappings of serializers that describe request and response bodies.
+
The appropriate OpenAPI operation object that describes
+ the endpoint, including path and query parameters for pagination, filtering,
+ and so on.
In compiling the schema, SchemaGenerator calls view.schema.get_operation()
-for each view, allowed method, and path.
+
+
In compiling the schema, SchemaGenerator calls get_components() and
+get_operation() for each view, allowed method, and path.
-
Note: For basic APIView subclasses, default introspection is essentially
-limited to the URL kwarg path parameters. For GenericAPIView
-subclasses, which includes all the provided class based views, AutoSchema will
-attempt to introspect serializer, pagination and filter fields, as well as
-provide richer path field descriptions. (The key hooks here are the relevant
-GenericAPIView attributes and methods: get_serializer, pagination_class,
-filter_backends and so on.)
+
Note: The automatic introspection of components, and many operation
+parameters relies on the relevant attributes and methods of
+GenericAPIView: get_serializer(), pagination_class, filter_backends,
+etc. For basic APIView subclasses, default introspection is essentially limited to
+the URL kwarg path parameters for this reason.
-
In order to customize the operation generation, you should provide an AutoSchema subclass, overriding get_operation() as you need:
-
from rest_framework.views import APIView
- from rest_framework.schemas.openapi import AutoSchema
-
- class CustomSchema(AutoSchema):
- def get_operation(...):
- # Implement custom introspection here (or in other sub-methods)
-
- class CustomView(APIView):
- """APIView subclass with custom schema introspection."""
- schema = CustomSchema()
-
-
This provides complete control over view introspection.
-
You may disable schema generation for a view by setting schema to None:
-
class CustomView(APIView):
- ...
- schema = None # Will not appear in schema
-
Tag name will be first element from the path. Also, any _ in path name will be replaced by a -.
-Consider below examples.
-
Example 1: Consider a user management system. The following table will illustrate the tag generation logic.
-Here first element from the paths is: users. Hence tag wil be users
-
-
-
-
Http Method
-
Path
-
Tags
-
-
-
-
-
PUT, PATCH, GET(Retrieve), DELETE
-
/users/{id}/
-
['users']
-
-
-
POST, GET(List)
-
/users/
-
['users']
-
-
-
-
Example 2: Consider a restaurant management system. The System has restaurants. Each restaurant has branches.
-Consider REST APIs to deal with a branch of a particular restaurant.
-Here first element from the paths is: restaurants. Hence tag wil be restaurants.
-
-
-
-
Http Method
-
Path
-
Tags
-
-
-
-
-
PUT, PATCH, GET(Retrieve), DELETE:
-
/restaurants/{restaurant_id}/branches/{branch_id}
-
['restaurants']
-
-
-
POST, GET(List):
-
/restaurants/{restaurant_id}/branches/
-
['restaurants']
-
-
-
-
Example 3: Consider Order items for an e commerce company.
The schema generator generates an operationid for each operation. This operationId is deduced from the model name, serializer name or view name. The operationId may looks like "listItems", "retrieveItem", "updateItem", etc..
-The operationId is camelCase by convention.
-
If you have several views with the same model, the generator may generate duplicate operationId.
-In order to work around this, you can override the second part of the operationId: operation name.
-
from rest_framework.schemas.openapi import AutoSchema
-
-class ExampleView(APIView):
- """APIView subclass with custom schema introspection."""
- schema = AutoSchema(operation_id_base="Custom")
-
-
-
The previous example will generate the following operationId: "listCustoms", "retrieveCustom", "updateCustom", "partialUpdateCustom", "destroyCustom".
-You need to provide the singular form of he operation name. For the list operation, a "s" will be appended at the end of the operation.
-
If you need more configuration over the operationId field, you can override the get_operation_id_base and get_operation_id methods from the AutoSchema class:
+
AutoSchema encapsulates the view introspection needed for schema generation.
+Because of this all the schema generation logic is kept in a single place,
+rather than being spread around the already extensive view, serializer and
+field APIs.
+
Keeping with this pattern, try not to let schema logic leak into your own
+views, serializers, or fields when customizing the schema generation. You might
+be tempted to do something like this:
Since DRF 3.12, Schema uses the OpenAPI Components. This method defines components in the schema and references them inside request and response objects. By default, the component's name is deduced from the Serializer's name.
-
Using OpenAPI's components provides the following advantages:
-
-
The schema is more readable and lightweight.
-
If you use the schema to generate an SDK (using openapi-generator or swagger-codegen). The generator can name your SDK's models.
You may get the following error while generating the schema:
-
"Serializer" is an invalid class name for schema generation.
-Serializer's class name should be unique and explicit. e.g. "ItemSerializer".
-
-
-
This error occurs when the Serializer name is "Serializer". You should choose a component's name unique across your schema and different than "Serializer".
-
You may also get the following warning:
-
Schema component "ComponentName" has been overriden with a different value.
-
-
-
This warning occurs when different components have the same name in one schema. Your component name should be unique across your project. This is likely an error that may lead to an invalid schema.
-
You have two ways to solve the previous issues:
-
-
You can rename your serializer with a unique name and another name than "Serializer".
-
You can set the component_name kwarg parameter of the AutoSchema constructor (see below).
-
You can override the get_component_name method of the AutoSchema class (see below).
If you want to have more control and customization about how the schema's components are generated, you can override the get_component_name and get_components method from the AutoSchema class.
-
from rest_framework.schemas.openapi import AutoSchema
-
-class CustomSchema(AutoSchema):
- def get_components(self, path, method):
- # Implement your custom implementation
-
- def get_component_name(self, serializer):
- # Implement your custom implementation
+ """
+ AutoSchema subclass using schema_extra_info on the view.
+ """
+ ...
+
+class CustomView(APIView):
+ schema = CustomSchema()
+ schema_extra_info = ... some extra info ...
+
+
+
Here, the AutoSchema subclass goes looking for schema_extra_info on the
+view. This is OK (it doesn't actually hurt) but it means you'll end up with
+your schema logic spread out in a number of different places.
+
Instead try to subclass AutoSchema such that the extra_info doesn't leak
+out into the view:
+
class BaseSchema(AutoSchema):
+ """
+ AutoSchema subclass that knows how to use extra_info.
+ """
+ ...
+
+class CustomSchema(BaseSchema):
+ extra_info = ... some extra info ...
class CustomView(APIView):
- """APIView subclass with custom schema introspection."""
schema = CustomSchema()
+
+
This style is slightly more verbose but maintains the encapsulation of the
+schema related code. It's more cohesive in the parlance. It'll keep the
+rest of your API code more tidy.
+
If an option applies to many view classes, rather than creating a specific
+subclass per-view, you may find it more convenient to allow specifying the
+option as an __init__() kwarg to your base AutoSchema subclass:
+
class CustomSchema(BaseSchema):
+ def __init__(self, **kwargs):
+ # store extra_info for later
+ self.extra_info = kwargs.pop("extra_info")
+ super().__init__(**kwargs)
+
+class CustomView(APIView):
+ schema = CustomSchema(
+ extra_info=... some extra info ...
+ )
+
+
+
This saves you having to create a custom subclass per-view for a commonly used option.
+
Not all AutoSchema methods expose related __init__() kwargs, but those for
+the more commonly needed options do.
Generates the OpenAPI components that describe request and response bodies,
+deriving their properties from the serializer.
+
Returns a dictionary mapping the component name to the generated
+representation. By default this has just a single pair but you may override
+get_components() to return multiple pairs if your view uses multiple
+serializers.
Computes the component's name from the serializer.
+
You may see warnings if your API has duplicate component names. If so you can override get_component_name() or pass the component_name__init__() kwarg (see below) to provide different names.
Maps serializers to their OpenAPI representations.
+
Most serializers should conform to the standard OpenAPI object type, but you may
+wish to override map_serializer() in order to customize this or other
+serializer-level fields.
Maps individual serializer fields to their schema representation. The base implementation
+will handle the default fields that Django REST Framework provides.
+
For SerializerMethodField instances, for which the schema is unknown, or custom field subclasses you should override map_field() to generate the correct schema:
+
class CustomSchema(AutoSchema):
+ """Extension of ``AutoSchema`` to add support for custom field schemas."""
+
+ def map_field(self, field):
+ # Handle SerializerMethodFields or custom fields here...
+ # ...
+ return super().map_field(field)
+
+
+
Authors of third-party packages should aim to provide an AutoSchema subclass,
+and a mixin, overriding map_field() so that users can easily generate schemas
+for their custom fields.
OpenAPI groups operations by tags. By default tags taken from the first path
+segment of the routed URL. For example, a URL like /users/{id}/ will generate
+the tag users.
+
You can pass an __init__() kwarg to manually specify tags (see below), or
+override get_tags() to provide custom logic.
There must be a unique operationid for each operation.
+By default the operationId is deduced from the model name, serializer name or
+view name. The operationId looks like "listItems", "retrieveItem",
+"updateItem", etc. The operationId is camelCase by convention.
Assuming a Pet model and PetSerializer serializer, the kwargs in this
+example are probably not needed. Often, though, you'll need to pass the kwargs
+if you have multiple view targeting the same model, or have multiple views with
+identically named serializers.
+
If your views have related customizations that are needed frequently, you can
+create a base AutoSchema subclass for your project that takes additional
+__init__() kwargs to save subclassing AutoSchema for each view.
The ModelSerializer class also exposes an API that you can override in order to alter how serializer fields are automatically determined when instantiating the serializer.
Normally if a ModelSerializer does not generate the fields you need by default then you should either add them to the class explicitly, or simply use a regular Serializer class instead. However in some cases you may want to create a new base class that defines how the serializer fields are created for any given model.
A mapping of Django model classes to REST framework serializer classes. You can override this mapping to alter the default serializer classes that should be used for each model class.
+
A mapping of Django model fields to REST framework serializer fields. You can override this mapping to alter the default serializer fields that should be used for each model field.
The drf-encrypt-content package helps you encrypt your data, serialized through ModelSerializer. It also contains some helper functions. Which helps you to encrypt your data.
The following methods are called directly by the view's .dispatch() method.
These perform any actions that need to occur before or after calling the handler methods such as .get(), .post(), put(), patch() and .delete().
Performs any actions that need to occur before the handler method gets called.
This method is used to enforce permissions and throttling, and perform content negotiation.
You won't typically need to override this method.
@@ -537,10 +541,10 @@ This method is used to enforce permissions and throttling, and perform content n
Any exception thrown by the handler method will be passed to this method, which either returns a Response instance, or re-raises the exception.
The default implementation handles any subclass of rest_framework.exceptions.APIException, as well as Django's Http404 and PermissionDenied exceptions, and returns an appropriate error response.
If you need to customize the error responses your API returns you should subclass this method.
Ensures that any Response object returned from the handler method will be rendered into the correct content type, as determined by the content negotiation.
The reason behind this is that Django's ValidationError class is intended for use with HTML forms and its API makes using it slightly awkward with nested validation errors that can occur in serializers.
For most users this change shouldn't require any updates to your codebase, but it is worth ensuring that whenever raising validation errors you should prefer using the serializers.ValidationError exception class, and not Django's built-in exception.
We strongly recommend that you use the namespaced import style of import serializers and not from serializers import ValidationError in order to avoid any potential confusion.
The validate_<field_name> method hooks that can be attached to serializer classes change their signature slightly and return type. Previously these would take a dictionary of all incoming data, and a key representing the field name, and would return a dictionary including the validated data for that field:
def validate_score(self, attrs, source):
if attrs['score'] % 10 != 0:
@@ -605,7 +609,7 @@ def create(self, validated_data):
raise serializers.ValidationError({'my_field': 'A field error'})
This ensures you can still write validation that compares all the input fields, but that marks the error against a particular field.
The under-used transform_<field_name> on serializer classes is no longer provided. Instead you should just override to_representation() if you need to apply any modifications to the representation style.
REST framework 3.12 brings a handful of refinements to the OpenAPI schema
+generation, plus support for Django's new database-agnostic JSONField,
+and some improvements to the SearchFilter class.
REST framework automatically determines operation IDs to use in OpenAPI
+schemas. The latest version provides more control for overriding the behaviour
+used to generate the operation IDs.
In order to output more graceful OpenAPI schemes, REST framework 3.12 now
+defines components in the schema, and then references them inside request
+and response objects. This is in contrast with the previous approach, which
+fully expanded the request and response bodies for each operation.
Many methods on the AutoSchema class have now been promoted to public API,
+allowing you to more fully customize the schema generation. The following methods
+are now available for overriding...
+
+
get_path_parameters
+
get_pagination_parameters
+
get_filter_parameters
+
get_request_body
+
get_responses
+
get_serializer
+
get_paginator
+
map_serializer
+
map_field
+
map_choice_field
+
map_field_validators
+
allows_filters.
+
+
See the schema docs
+for details on using custom AutoSchema subclasses.
The class now supports nested search within JSONField and HStoreField, using
+the double underscore notation for traversing which element of the field the
+search should apply to.
+
class SitesSearchView(generics.ListAPIView):
+ """
+ An API view to return a list of archaeological sites, optionally filtered
+ by a search against the site name or location. (Location searches are
+ matched against the region and country names.)
+ """
+ queryset = Sites.objects.all()
+ serializer_class = SitesSerializer
+ filter_backends = [filters.SearchFilter]
+ search_fields = ['site_name', 'location__region', 'location__country']
+
Django allows querysets to create additional virtual fields, using the .annotate
+method. We now support searching against annotate fields.
+
class PublisherSearchView(generics.ListAPIView):
+ """
+ Search for publishers, optionally filtering the search against the average
+ rating of all their books.
+ """
+ queryset = Publisher.objects.annotate(avg_rating=Avg('book__rating'))
+ serializer_class = PublisherSerializer
+ filter_backends = [filters.SearchFilter]
+ search_fields = ['avg_rating']
+
REST framework is a collaboratively funded project. If you use
+REST framework commercially we strongly encourage you to invest in its
+continued development by signing up for a paid plan.
+
Every single sign-up helps us make REST framework long-term financially sustainable.
Add --file option to generateschema command. [#7130]
+
Support tags for OpenAPI schema generation. See the schema docs. [#7184]
+
Support customising the operation ID for schema generation. See the schema docs. [#7190]
+
Support OpenAPI components for schema generation. See the schema docs. [#7124]
+
The following methods on AutoSchema become public API: get_path_parameters, get_pagination_parameters, get_filter_parameters, get_request_body, get_responses, get_serializer, get_paginator, map_serializer, map_field, map_choice_field, map_field_validators, allows_filters. See the schema docs
+
Add support for Django 3.1's database-agnositic JSONField. [#7467]
+
SearchFilter now supports nested search on JSONField and HStoreField model fields. [#7121]
+
SearchFilter now supports searching on annotate() fields. [#6240]
+
The authtoken model no longer exposes the pk in the admin URL. [#7341]
+
Add __repr__ for Request instances. [#7239]
+
UTF-8 decoding with Latin-1 fallback for basic auth credentials. [#7193]
+
CharField treats surrogate characters as a validation failure. [#7026]
+
Don't include callables as default values in schemas. [#7105]
+
Improve ListField schema output to include all available child information. [#7137]
+
Allow default=False to be included for BooleanField schema outputs. [#7165]
+
Include "type" information in ChoiceField schema outputs. [#7161]
+
Include "type": "object" on schema objects. [#7169]
+
Don't include component in schema output for DELETE requests. [#7229]
+
Fix schema types for DecimalField. [#7254]
+
Fix schema generation for ObtainAuthToken view. [#7211]
+
Support passing context=... to view .get_serializer() methods. [#7298]
+
Pass custom code to PermissionDenied if permission class has one set. [#7306]
+
Include "example" in schema pagination output. [#7275]
+
Default status code of 201 on schema output for POST requests. [#7206]
+
Use camelCase for operation IDs in schema output. [#7208]
+
Warn if duplicate operation IDs exist in schema output. [#7207]
+
Improve handling of decimal type when mapping ChoiceField to a schema output. [#7264]
+
Disable YAML aliases for OpenAPI schema outputs. [#7131]
+
Fix action URL names for APIs included under a namespaced URL. [#7287]
+
Update jQuery version from 3.4 to 3.5. [#7313]
+
Fix UniqueTogether handling when serializer fields use source=.... [#7143]
+
HTTP HEAD requests now set self.action correctly on a ViewSet instance. [#7223]
+
Return a valid OpenAPI schema for the case where no API schema paths exist. [#7125]
+
Include tests in package distribution. [#7145]
+
Allow type checkers to support annotations like ModelSerializer[Author]. [#7385]
+
Don't include invalid charset=None portion in the request Content-Type header when using APIClient. [#7400]
+
Fix \Z/\z tokens in OpenAPI regexs. [#7389]
+
Fix PrimaryKeyRelatedField and HyperlinkedRelatedField when source field is actually a property. [#7142]
+
Token.generate_key is now a class method. [#7502]
+
@action warns if method is wrapped in a decorator that does not preserve information using @functools.wraps. [#7098]
rest_condition - Another extension for building complex permissions in a simple and convenient way.
-
dry-rest-permissions - Provides a simple way to define permissions for individual api actions.
+
dry-rest-permissions - Provides a simple way to define permissions for individual api actions.
drf-access-policy - Declarative and flexible permissions inspired by AWS' IAM policies.
+
drf-psq - An extension that gives support for having action-based permission_classes, serializer_class, and queryset dependent on permission-based rules.
djangorestframework-jsonapi - Provides a parser, renderer, serializers, and other tools to help build an API that is compliant with the jsonapi.org spec.
-
drf_ujson - Implements JSON rendering using the UJSON package.
+
drf_ujson2 - Implements JSON rendering using the UJSON package.
rest-pandas - Pandas DataFrame-powered renderers including Excel, CSV, and SVG formats.
@@ -452,7 +456,7 @@ are optional but recommended.
urlpatterns = [
...
- url(r'^docs/', include_docs_urls(title='My API title'))
+ path('docs/', include_docs_urls(title='My API title'))
]
This will include two different views:
@@ -470,7 +474,7 @@ This means that views will not be instantiated with a request insta
urlpatterns = [
...
# Generate schema with valid `request` instance:
- url(r'^docs/', include_docs_urls(title='My API title', public=False))
+ path('docs/', include_docs_urls(title='My API title', public=False))
]
diff --git a/coreapi/index.html b/coreapi/index.html
index 876c51370..e681f434d 100644
--- a/coreapi/index.html
+++ b/coreapi/index.html
@@ -47,7 +47,7 @@
}
-
+
drf-yasg generates OpenAPI documents suitable for code generation - nested schemas,
named models, response bodies, enum/pattern/min/max validators, form parameters, etc.
drf-spectacular is a OpenAPI 3 schema generation tool with explicit focus on extensibility,
+customizability and client generation. It's usage patterns are very similar to drf-yasg.