Data structures, not algorithms, are central to programming.
— Rob Pike
Relational fields are used to represent model relationships. They can be applied to ForeignKey, ManyToManyField and OneToOneField relationships, as well as to reverse relationships, and custom relationships such as GenericForeignKey.
Note: The relational fields are declared in relations.py, but by convention you should import them from the serializers module, using from rest_framework import serializers and refer to fields as serializers.<FieldName>.
When using the ModelSerializer class, serializer fields and relationships will be automatically generated for you. Inspecting these automatically generated fields can be a useful tool for determining how to customize the relationship style.
To do so, open the Django shell, using python manage.py shell, then import the serializer class, instantiate it, and print the object representation…
In order to explain the various types of relational fields, we'll use a couple of simple models for our examples. Our models will be for music albums, and the tracks listed on each album.
StringRelatedField may be used to represent the target of the relationship using its __str__ method.
For example, the following serializer:
Would serialize to the following representation:
This field is read only.
Arguments:
PrimaryKeyRelatedField may be used to represent the target of the relationship using its primary key.
For example, the following serializer:
Would serialize to a representation like this:
By default this field is read-write, although you can change this behavior using the read_only flag.
Arguments:
HyperlinkedRelatedField may be used to represent the target of the relationship using a hyperlink.
For example, the following serializer:
Would serialize to a representation like this:
By default this field is read-write, although you can change this behavior using the read_only flag.
Note: This field is designed for objects that map to a URL that accepts a single URL keyword argument, as set using the lookup_field and lookup_url_kwarg arguments.
This is suitable for URLs that contain a single primary key or slug argument as part of the URL.
If you require more complex hyperlinked representation you'll need to customize the field, as described in the custom hyperlinked fields section, below.
Arguments:
SlugRelatedField may be used to represent the target of the relationship using a field on the target.
For example, the following serializer:
Would serialize to a representation like this:
By default this field is read-write, although you can change this behavior using the read_only flag.
When using SlugRelatedField as a read-write field, you will normally want to ensure that the slug field corresponds to a model field with unique=True.
Arguments:
This field can be applied as an identity relationship, such as the 'url' field on a HyperlinkedModelSerializer. It can also be used for an attribute on the object. For example, the following serializer:
Would serialize to a representation like this:
This field is always read-only.
Arguments:
As opposed to previously discussed references to another entity, the referred entity can instead also be embedded or nested in the representation of the object that refers to it. Such nested relationships can be expressed by using serializers as fields.
If the field is used to represent a to-many relationship, you should add the many=True flag to the serializer field.
For example, the following serializer:
Would serialize to a nested representation like this:
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:
In rare cases where none of the existing relational styles fit the representation you need, you can implement a completely custom relational field, that describes exactly how the output representation should be generated from the model instance.
To implement a custom relational field, you should override RelatedField, and implement the .to_representation(self, value) method. This method takes the target of the field as the value argument, and should return the representation that should be used to serialize the target. The value argument will typically be a 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:
This custom field would then serialize to the following representation:
In some cases you may need to customize the behavior of a hyperlinked field, in order to represent URLs that require more than a single lookup field.
You can achieve this by overriding HyperlinkedRelatedField. There are two methods that may be overridden:
get_url(self, obj, view_name, request, format)
The get_url method is used to map the object instance to its URL representation.
May raise a NoReverseMatch if the view_name and lookup_field attributes are not configured to correctly match the URL conf.
get_object(self, view_name, view_args, view_kwargs)
If you want to support a writable hyperlinked field then you'll also want to override get_object, in order to map incoming URLs back to the object they represent. For read-only hyperlinked fields there is no need to override this method.
The return value of this method should the object that corresponds to the matched URL conf arguments.
May raise an ObjectDoesNotExist exception.
Say we have a URL for a customer object that takes two keyword arguments, like so:
This cannot be represented with the default implementation, which accepts only a single lookup field.
In this case we'd need to override HyperlinkedRelatedField to get the behavior we want:
Note that if you wanted to use this style together with the generic views then you'd also need to override .get_object on the view in order to get the correct lookup behavior.
Generally we recommend a flat style for API representations where possible, but the nested URL style can also be reasonable when used in moderation.
The queryset argument is only ever required for writable relationship field, in which case it is used for performing the model instance lookup, that maps from the primitive user input, into a model instance.
In version 2.x a serializer class could sometimes automatically determine the queryset argument if a ModelSerializer class was being used.
This behavior is now replaced with always using an explicit queryset argument for writable relational fields.
Doing so reduces the amount of hidden 'magic' that ModelSerializer provides, makes the behavior of the field more clear, and ensures that it is trivial to move between using the ModelSerializer shortcut, or using fully explicit Serializer classes.
The built-in __str__ method of the model will be used to generate string representations of the objects used to populate the choices property. These choices are used to populate select HTML inputs in the browsable API.
To provide customized representations for such inputs, override display_value() of a RelatedField subclass. This method will receive a model object, and should return a string suitable for representing it. For example:
When rendered in the browsable API relational fields will default to only displaying a maximum of 1000 selectable items. If more items are present then a disabled option with "More than 1000 items…" will be displayed.
This behavior is intended to prevent a template from being unable to render in an acceptable timespan due to a very large number of relationships being displayed.
There are two keyword arguments you can use to control this behavior:
You can also control these globally using the settings HTML_SELECT_CUTOFF and HTML_SELECT_CUTOFF_TEXT.
In cases where the cutoff is being enforced you may want to instead use a plain input field in the HTML form. You can do so using the style keyword argument. For example:
Note that reverse relationships are not automatically included by the ModelSerializer and HyperlinkedModelSerializer classes. To include a reverse relationship, you must explicitly add it to the fields list. For example:
You'll normally want to ensure that you've set an appropriate related_name argument on the relationship, that you can use as the field name. For example:
If you have not set a related name for the reverse relationship, you'll need to use the automatically generated related name in the fields argument. For example:
See the Django documentation on reverse relationships for more details.
If you want to serialize a generic foreign key, you need to define a custom field, to determine explicitly how you want to serialize the targets of the relationship.
For example, given the following model for a tag, which has a generic relationship with other arbitrary models:
And the following two models, which may have associated tags:
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:
If you need the target of the relationship to have a nested representation, you can use the required serializers inside the .to_representation() method:
Note that reverse generic keys, expressed using the GenericRelation field, can be serialized using the regular relational field types, since the type of the target in the relationship is always known.
For more information see the Django documentation on generic relations.
By default, relational fields that target a ManyToManyField with a through model specified are set to read-only.
If you explicitly specify a relational field pointing to a ManyToManyField with a through model, be sure to set read_only to True.
If you wish to represent extra fields on a through model then you may serialize the through model as a nested object.
The following third party packages are also available.
The drf-nested-routers package provides routers and relationship fields for working with nested resources.
The rest-framework-generic-relations library provides read/write serialization for generic foreign keys.
relations.py


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.
— Django documentation
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.
The set of valid renderers for a view is always defined as a list of classes. When a view is entered REST framework will perform content negotiation on the incoming request, and determine the most appropriate renderer to satisfy the request.
The basic process of content negotiation involves examining the request's Accept header, to determine which media types it expects in the response. Optionally, format suffixes on the URL may be used to explicitly request a particular representation. For example the URL http://example.com/api/users_count.json might be an endpoint that always returns JSON data.
For more information see the documentation on content negotiation.
The default set of renderers may be set globally, using the DEFAULT_RENDERER_CLASSES setting. For example, the following settings would use JSON as the main media type and also include the self describing API.
You can also set the renderers used for an individual view, or viewset, using the APIView class-based views.
Or, if you're using the @api_view decorator with function based views.
It's important when specifying the renderer classes for your API to think about what priority you want to assign to each media type. If a client underspecifies the representations it can accept, such as sending an Accept: */* header, or not including an Accept header at all, then REST framework will select the first renderer in the list to use for the response.
For example if your API serves JSON responses and the HTML browsable API, you might want to make JSONRenderer your default renderer, in order to send JSON responses to clients that do not specify an Accept header.
If your API includes views that can serve both regular webpages and API responses depending on the request, then you might consider making TemplateHTMLRenderer your default renderer, in order to play nicely with older browsers that send broken accept headers.
Renders the request data into JSON, using utf-8 encoding.
Note that the default style is to include unicode characters, and render the response using a compact style with no unnecessary whitespace:
The client may additionally include an 'indent' media type parameter, in which case the returned JSON will be indented. For example Accept: application/json; indent=4.
The default JSON encoding style can be altered using the UNICODE_JSON and COMPACT_JSON settings keys.
.media_type: application/json
.format: 'json'
.charset: None
Renders data to HTML, using Django's standard template rendering. Unlike other renderers, the data passed to the Response does not need to be serialized. Also, unlike other renderers, you may want to include a template_name argument when creating the Response.
The TemplateHTMLRenderer will create a RequestContext, using the response.data as the context dict, and determine a template name to use to render the context.
Note: When used with a view that makes use of a serializer the Response 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:
The template name is determined by (in order of preference):
An example of a view that uses TemplateHTMLRenderer:
You can use TemplateHTMLRenderer either to return regular HTML pages using REST framework, or to return both HTML and API responses from a single endpoint.
If you're building websites that use TemplateHTMLRenderer along with other renderer classes, you should consider listing TemplateHTMLRenderer as the first class in the renderer_classes list, so that it will be prioritised first even for browsers that send poorly formed ACCEPT: headers.
See the HTML & Forms Topic Page for further examples of TemplateHTMLRenderer usage.
.media_type: text/html
.format: 'html'
.charset: utf-8
See also: StaticHTMLRenderer
A simple renderer that simply returns pre-rendered HTML. Unlike other renderers, the data passed to the response object should be a string representing the content to be returned.
An example of a view that uses StaticHTMLRenderer:
You can use StaticHTMLRenderer either to return regular HTML pages using REST framework, or to return both HTML and API responses from a single endpoint.
.media_type: text/html
.format: 'html'
.charset: utf-8
See also: TemplateHTMLRenderer
Renders data into HTML for the Browsable API:
This renderer will determine which other renderer would have been given highest priority, and use that to display an API style response within the HTML page.
.media_type: text/html
.format: 'api'
.charset: utf-8
.template: 'rest_framework/api.html'
By default the response content will be rendered with the highest priority renderer apart from BrowsableAPIRenderer. If you need to customize this behavior, for example to use HTML as the default return format, but use JSON in the browsable API, you can do so by overriding the get_default_renderer() method. For example:
Renders data into HTML for an admin-like display:
This renderer is suitable for CRUD-style web APIs that should also present a user-friendly interface for managing the data.
Note that views that have nested or list serializers for their input won't work well with the AdminRenderer, as the HTML forms are unable to properly support them.
Note: The AdminRenderer is only able to include links to detail pages when a properly configured URL_FIELD_NAME (url by default) attribute is present in the data. For HyperlinkedModelSerializer this will be the case, but for ModelSerializer or plain Serializer classes you'll need to make sure to include the field explicitly. For example here we use models get_absolute_url method:
.media_type: text/html
.format: 'admin'
.charset: utf-8
.template: 'rest_framework/admin.html'
Renders data returned by a serializer into an HTML form. The output of this renderer does not include the enclosing <form> tags, a hidden CSRF input or any submit buttons.
This renderer is not intended to be used directly, but can instead be used in templates by passing a serializer instance to the render_form template tag.
For more information see the HTML & Forms documentation.
.media_type: text/html
.format: 'form'
.charset: utf-8
.template: 'rest_framework/horizontal/form.html'
This renderer is used for rendering HTML multipart form data. It is not suitable as a response renderer, but is instead used for creating test requests, using REST framework's test client and test request factory.
.media_type: multipart/form-data; boundary=BoUnDaRyStRiNg
.format: 'multipart'
.charset: utf-8
To implement a custom renderer, you should override BaseRenderer, set the .media_type and .format properties, and implement the .render(self, data, media_type=None, renderer_context=None) method.
The method should return a bytestring, which will be used as the body of the HTTP response.
The arguments passed to the .render() method are:
The request data, as set by the Response() instantiation.
Optional. If provided, this is the accepted media type, as determined by the content negotiation stage.
Depending on the client's Accept: header, this may be more specific than the renderer's media_type attribute, and may include media type parameters. For example "application/json; nested=true".
Optional. If provided, this is a dictionary of contextual information provided by the view.
By default this will include the following keys: view, request, response, args, kwargs.
The following is an example plaintext renderer that will return a response with the data parameter as the content of the response.
By default renderer classes are assumed to be using the UTF-8 encoding. To use a different encoding, set the charset attribute on the renderer.
Note that if a renderer class returns a unicode string, then the response content will be coerced into a bytestring by the Response class, with the charset attribute set on the renderer used to determine the encoding.
If the renderer returns a bytestring representing raw binary content, you should set a charset value of None, which will ensure the Content-Type header of the response will not have a charset value set.
In some cases you may also want to set the render_style attribute to 'binary'. Doing so will also ensure that the browsable API will not attempt to display the binary content as a string.
You can do some pretty flexible things using REST framework's renderers. Some examples...
In some cases you might want your view to use different serialization styles depending on the accepted media type. If you need to do this you can access request.accepted_renderer to determine the negotiated renderer that will be used for the response.
For example:
In some cases you might want a renderer to serve a range of media types. In this case you can underspecify the media types it should respond to, by using a media_type value such as image/*, or */*.
If you underspecify the renderer's media type, you should make sure to specify the media type explicitly when you return the response, using the content_type attribute. For example:
For the purposes of many Web APIs, simple JSON responses with hyperlinked relations may be sufficient. If you want to fully embrace RESTful design and HATEOAS you'll need to consider the design and usage of your media types in more detail.
In the words of Roy Fielding, "A REST API should spend almost all of its descriptive effort in defining the media type(s) used for representing resources and driving application state, or in defining extended relation names and/or hypertext-enabled mark-up for existing standard media types.".
For good examples of custom media types, see GitHub's use of a custom application/vnd.github+json media type, and Mike Amundsen's IANA approved application/vnd.collection+json JSON-based hypermedia.
Typically a renderer will behave the same regardless of if it's dealing with a regular response, or with a response caused by an exception being raised, such as an Http404 or PermissionDenied exception, or a subclass of APIException.
If you're using either the TemplateHTMLRenderer or the StaticHTMLRenderer and an exception is raised, the behavior is slightly different, and mirrors Django's default handling of error views.
Exceptions raised and handled by an HTML renderer will attempt to render using one of the following methods, by order of precedence.
Templates will render with a RequestContext which includes the status_code and details keys.
Note: If DEBUG=True, Django's standard traceback error page will be displayed instead of rendering the HTTP status code and text.
The following third party packages are also available.
REST framework YAML provides YAML parsing and rendering support. It was previously included directly in the REST framework package, and is now instead supported as a third-party package.
Install using pip.
Modify your REST framework settings.
REST Framework XML provides a simple informal XML format. It was previously included directly in the REST framework package, and is now instead supported as a third-party package.
Install using pip.
Modify your REST framework settings.
REST framework JSONP provides JSONP rendering support. It was previously included directly in the REST framework package, and is now instead supported as a third-party package.
Warning: If you require cross-domain AJAX requests, you should generally be using the more modern approach of CORS as an alternative to JSONP. See the CORS documentation for more details.
The jsonp approach is essentially a browser hack, and is only appropriate for globally readable API endpoints, where GET requests are unauthenticated and do not require any user permissions.
Install using pip.
Modify your REST framework settings.
MessagePack is a fast, efficient binary serialization format. Juan Riaza maintains the djangorestframework-msgpack package which provides MessagePack renderer and parser support for REST framework.
XLSX is the world's most popular binary spreadsheet format. Tim Allen of The Wharton School maintains drf-renderer-xlsx, which renders an endpoint as an XLSX spreadsheet using OpenPyXL, and allows the client to download it. Spreadsheets can be styled on a per-view basis.
Install using pip.
Modify your REST framework settings.
To avoid having a file streamed without a filename (which the browser will often default to the filename "download", with no extension), we need to use a mixin to override the Content-Disposition header. If no filename is provided, it will default to export.xlsx. For example:
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. 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.
Django REST Pandas provides a serializer and renderers that support additional data processing and output via the Pandas DataFrame API. Django REST Pandas includes renderers for Pandas-style CSV files, Excel workbooks (both .xls and .xlsx), and a number of other formats. It is maintained by S. Andrew Sheppard as part of the wq Project.
Rest Framework Latex provides a renderer that outputs PDFs using Laulatex. It is maintained by Pebble (S/F Software).
renderers.py


Code without tests is broken as designed.
— Jacob Kaplan-Moss
REST framework includes a few helper classes that extend Django's existing test framework, and improve support for making API requests.
Extends Django's existing RequestFactory class.
The APIRequestFactory class supports an almost identical API to Django's standard RequestFactory class. This means that the standard .get(), .post(), .put(), .patch(), .delete(), .head() and .options() methods are all available.
Methods which create a request body, such as post, put and patch, include a format argument, which make it easy to generate requests using a content type other than multipart form data. For example:
By default the available formats are 'multipart' and 'json'. For compatibility with Django's existing RequestFactory the default format is 'multipart'.
To support a wider set of request formats, or change the default format, see the configuration section.
If you need to explicitly encode the request body, you can do so by setting the content_type flag. For example:
One difference worth noting between Django's RequestFactory and REST framework's APIRequestFactory is that multipart form data will be encoded for methods other than just .post().
For example, using APIRequestFactory, you can make a form PUT request like so:
Using Django's RequestFactory, you'd need to explicitly encode the data yourself:
When testing views directly using a request factory, it's often convenient to be able to directly authenticate the request, rather than having to construct the correct authentication credentials.
To forcibly authenticate a request, use the force_authenticate() method.
The signature for the method is force_authenticate(request, user=None, token=None). When making the call, either or both of the user and token may be set.
For example, when forcibly authenticating using a token, you might do something like the following:
Note: force_authenticate directly sets request.user to the in-memory user instance. If you are re-using the same user instance across multiple tests that update the saved user state, you may need to call refresh_from_db() between tests.
Note: When using APIRequestFactory, the object that is returned is Django's standard HttpRequest, and not REST framework's Request object, which is only generated once the view is called.
This means that setting attributes directly on the request object may not always have the effect you expect. For example, setting .token directly will have no effect, and setting .user directly will only work if session authentication is being used.
By default, requests created with APIRequestFactory will not have CSRF validation applied when passed to a REST framework view. If you need to explicitly turn CSRF validation on, you can do so by setting the enforce_csrf_checks flag when instantiating the factory.
Note: It's worth noting that Django's standard RequestFactory doesn't need to include this option, because when using regular Django the CSRF validation takes place in middleware, which is not run when testing views directly. When using REST framework, CSRF validation takes place inside the view, so the request factory needs to disable view-level CSRF checks.
Extends Django's existing Client class.
The APIClient class supports the same request interface as Django's standard Client class. This means that the standard .get(), .post(), .put(), .patch(), .delete(), .head() and .options() methods are all available. For example:
To support a wider set of request formats, or change the default format, see the configuration section.
The login method functions exactly as it does with Django's regular Client class. This allows you to authenticate requests against any views which include SessionAuthentication.
To logout, call the logout method as usual.
The login method is appropriate for testing APIs that use session authentication, for example web sites which include AJAX interaction with the API.
The credentials method can be used to set headers that will then be included on all subsequent requests by the test client.
Note that calling credentials a second time overwrites any existing credentials. You can unset any existing credentials by calling the method with no arguments.
The credentials method is appropriate for testing APIs that require authentication headers, such as basic authentication, OAuth1a and OAuth2 authentication, and simple token authentication schemes.
Sometimes you may want to bypass authentication entirely and force all requests by the test client to be automatically treated as authenticated.
This can be a useful shortcut if you're testing the API but don't want to have to construct valid authentication credentials in order to make test requests.
To unauthenticate subsequent requests, call force_authenticate setting the user and/or token to None.
By default CSRF validation is not applied when using APIClient. If you need to explicitly enable CSRF validation, you can do so by setting the enforce_csrf_checks flag when instantiating the client.
As usual CSRF validation will only apply to any session authenticated views. This means CSRF validation will only occur if the client has been logged in by calling login().
REST framework also includes a client for interacting with your application using the popular Python library, requests. This may be useful if:
This exposes exactly the same interface as if you were using a requests session directly.
Note that the requests client requires you to pass fully qualified URLs.
The RequestsClient class is useful if you want to write tests that solely interact with the service interface. This is a little stricter than using the standard Django test client, as it means that all interactions should be via the API.
If you're using RequestsClient you'll want to ensure that test setup, and results assertions are performed as regular API calls, rather than interacting with the database models directly. For example, rather than checking that Customer.objects.count() == 3 you would list the customers endpoint, and ensure that it contains three records.
Custom headers and authentication credentials can be provided in the same way as when using a standard requests.Session instance.
If you're using SessionAuthentication then you'll need to include a CSRF token for any POST, PUT, PATCH or DELETE requests.
You can do so by following the same flow that a JavaScript based client would use. First make a GET request in order to obtain a CRSF token, then present that token in the following request.
For example...
With careful usage both the RequestsClient and the CoreAPIClient provide the ability to write test cases that can run either in development, or be run directly against your staging server or production environment.
Using this style to create basic tests of a few core piece of functionality is a powerful way to validate your live service. Doing so may require some careful attention to setup and teardown to ensure that the tests run in a way that they do not directly affect customer data.
The CoreAPIClient allows you to interact with your API using the Python coreapi client library.
Custom headers and authentication may be used with CoreAPIClient in a similar way as with RequestsClient.
REST framework includes the following test case classes, that mirror the existing Django test case classes, but use APIClient instead of Django's default Client.
You can use any of REST framework's test case classes as you would for the regular Django test case classes. The self.client attribute will be an APIClient instance.
REST framework also provides a test case class for isolating urlpatterns on a per-class basis. Note that this inherits from Django's SimpleTestCase, and will most likely need to be mixed with another test case class.
When checking the validity of test responses it's often more convenient to inspect the data that the response was created with, rather than inspecting the fully rendered response.
For example, it's easier to inspect response.data:
Instead of inspecting the result of parsing response.content:
If you're testing views directly using APIRequestFactory, the responses that are returned will not yet be rendered, as rendering of template responses is performed by Django's internal request-response cycle. In order to access response.content, you'll first need to render the response.
The default format used to make test requests may be set using the TEST_REQUEST_DEFAULT_FORMAT setting key. For example, to always use JSON for test requests by default instead of standard multipart form requests, set the following in your settings.py file:
If you need to test requests using something other than multipart or json requests, you can do so by setting the TEST_REQUEST_RENDERER_CLASSES setting.
For example, to add support for using format='html' in test requests, you might have something like this in your settings.py file.
test.py


Exceptions… allow error handling to be organized cleanly in a central or high-level place within the program structure.
— Doug Hellmann, Python Exception Handling Techniques
REST framework's views handle various exceptions, and deal with returning appropriate error responses.
The handled exceptions are:
In each case, REST framework will return a response with an appropriate status code and content-type. The body of the response will include any additional details regarding the nature of the error.
Most error responses will include a key detail in the body of the response.
For example, the following request:
Might receive an error response indicating that the DELETE method is not allowed on that resource:
Validation errors are handled slightly differently, and will include the field names as the keys in the response. If the validation error was not specific to a particular field then it will use the "non_field_errors" key, or whatever string value has been set for the NON_FIELD_ERRORS_KEY setting.
An example validation error might look like this:
You can implement custom exception handling by creating a handler function that converts exceptions raised in your API views into response objects. This allows you to control the style of error responses used by your API.
The function must take a pair of arguments, the first is the exception to be handled, and the second is a dictionary containing any extra context such as the view currently being handled. The exception handler function should either return a Response object, or return None if the exception cannot be handled. If the handler returns None then the exception will be re-raised and Django will return a standard HTTP 500 'server error' response.
For example, you might want to ensure that all error responses include the HTTP status code in the body of the response, like so:
In order to alter the style of the response, you could write the following custom exception handler:
The context argument is not used by the default handler, but can be useful if the exception handler needs further information such as the view currently being handled, which can be accessed as context['view'].
The exception handler must also be configured in your settings, using the EXCEPTION_HANDLER setting key. For example:
If not specified, the 'EXCEPTION_HANDLER' setting defaults to the standard exception handler provided by REST framework:
Note that the exception handler will only be called for responses generated by raised exceptions. It will not be used for any responses returned directly by the view, such as the HTTP_400_BAD_REQUEST responses that are returned by the generic views when serializer validation fails.
Signature: APIException()
The base class for all exceptions raised inside an APIView class or @api_view.
To provide a custom exception, subclass APIException and set the .status_code, .default_detail, and default_code attributes on the class.
For example, if your API relies on a third party service that may sometimes be unreachable, you might want to implement an exception for the "503 Service Unavailable" HTTP response code. You could do this like so:
There are a number of different properties available for inspecting the status of an API exception. You can use these to build custom exception handling for your project.
The available attributes and methods are:
In most cases the error detail will be a simple item:
In the case of validation errors the error detail will be either a list or dictionary of items:
Signature: ParseError(detail=None, code=None)
Raised if the request contains malformed data when accessing request.data.
By default this exception results in a response with the HTTP status code "400 Bad Request".
Signature: AuthenticationFailed(detail=None, code=None)
Raised when an incoming request includes incorrect authentication.
By default this exception results in a response with the HTTP status code "401 Unauthenticated", but it may also result in a "403 Forbidden" response, depending on the authentication scheme in use. See the authentication documentation for more details.
Signature: NotAuthenticated(detail=None, code=None)
Raised when an unauthenticated request fails the permission checks.
By default this exception results in a response with the HTTP status code "401 Unauthenticated", but it may also result in a "403 Forbidden" response, depending on the authentication scheme in use. See the authentication documentation for more details.
Signature: PermissionDenied(detail=None, code=None)
Raised when an authenticated request fails the permission checks.
By default this exception results in a response with the HTTP status code "403 Forbidden".
Signature: NotFound(detail=None, code=None)
Raised when a resource does not exists at the given URL. This exception is equivalent to the standard Http404 Django exception.
By default this exception results in a response with the HTTP status code "404 Not Found".
Signature: MethodNotAllowed(method, detail=None, code=None)
Raised when an incoming request occurs that does not map to a handler method on the view.
By default this exception results in a response with the HTTP status code "405 Method Not Allowed".
Signature: NotAcceptable(detail=None, code=None)
Raised when an incoming request occurs with an Accept header that cannot be satisfied by any of the available renderers.
By default this exception results in a response with the HTTP status code "406 Not Acceptable".
Signature: UnsupportedMediaType(media_type, detail=None, code=None)
Raised if there are no parsers that can handle the content type of the request data when accessing request.data.
By default this exception results in a response with the HTTP status code "415 Unsupported Media Type".
Signature: Throttled(wait=None, detail=None, code=None)
Raised when an incoming request fails the throttling checks.
By default this exception results in a response with the HTTP status code "429 Too Many Requests".
Signature: ValidationError(detail, code=None)
The ValidationError exception is slightly different from the other APIException classes:
The ValidationError class should be used for serializer and field validation, and by validator classes. It is also raised when calling serializer.is_valid with the raise_exception keyword argument:
The generic views use the raise_exception=True flag, which means that you can override the style of validation error responses globally in your API. To do so, use a custom exception handler, as described above.
By default this exception results in a response with the HTTP status code "400 Bad Request".
Django REST Framework provides two error views suitable for providing generic JSON 500 Server Error and 400 Bad Request responses. (Django's default error views provide HTML responses, which may not be appropriate for an API-only application.)
Use these as per Django's Customizing error views documentation.
Returns a response with status code 500 and application/json content type.
Set as handler500:
Returns a response with status code 400 and application/json content type.
Set as handler400:
exceptions.py


HTTP/1.1 420 Enhance Your Calm
Twitter API rate limiting response
Throttling is similar to permissions, in that it determines if a request should be authorized. Throttles indicate a temporary state, and are used to control the rate of requests that clients can make to an API.
As with permissions, multiple throttles may be used. Your API might have a restrictive throttle for unauthenticated requests, and a less restrictive throttle for authenticated requests.
Another scenario where you might want to use multiple throttles would be if you need to impose different constraints on different parts of the API, due to some services being particularly resource-intensive.
Multiple throttles can also be used if you want to impose both burst throttling rates, and sustained throttling rates. For example, you might want to limit a user to a maximum of 60 requests per minute, and 1000 requests per day.
Throttles do not necessarily only refer to rate-limiting requests. For example a storage service might also need to throttle against bandwidth, and a paid data service might want to throttle against a certain number of a records being accessed.
As with permissions and authentication, throttling in REST framework is always defined as a list of classes.
Before running the main body of the view each throttle in the list is checked. If any throttle check fails an exceptions.Throttled exception will be raised, and the main body of the view will not run.
The default throttling policy may be set globally, using the DEFAULT_THROTTLE_CLASSES and DEFAULT_THROTTLE_RATES settings. For example.
The rate descriptions used in DEFAULT_THROTTLE_RATES may include second, minute, hour or day as the throttle period.
You can also set the throttling policy on a per-view or per-viewset basis, using the APIView class-based views.
If you're using the @api_view decorator with function based views you can use the following decorator.
It's also possible to set throttle classes for routes that are created using the @action decorator. Throttle classes set in this way will override any viewset level class settings.
The X-Forwarded-For HTTP header and REMOTE_ADDR WSGI variable are used to uniquely identify client IP addresses for throttling. If the X-Forwarded-For header is present then it will be used, otherwise the value of the REMOTE_ADDR variable from the WSGI environment will be used.
If you need to strictly identify unique client IP addresses, you'll need to first configure the number of application proxies that the API runs behind by setting the NUM_PROXIES setting. This setting should be an integer of zero or more. If set to non-zero then the client IP will be identified as being the last IP address in the X-Forwarded-For header, once any application proxy IP addresses have first been excluded. If set to zero, then the REMOTE_ADDR value will always be used as the identifying IP address.
It is important to understand that if you configure the NUM_PROXIES setting, then all clients behind a unique NAT'd gateway will be treated as a single client.
Further context on how the X-Forwarded-For header works, and identifying a remote client IP can be found here.
The throttle classes provided by REST framework use Django's cache backend. You should make sure that you've set appropriate cache settings. The default value of LocMemCache backend should be okay for simple setups. See Django's cache documentation for more details.
If you need to use a cache other than 'default', you can do so by creating a custom throttle class and setting the cache attribute. For example:
You'll need to remember to also set your custom throttle class in the 'DEFAULT_THROTTLE_CLASSES' settings key, or using the throttle_classes view attribute.
The AnonRateThrottle will only ever throttle unauthenticated users. The IP address of the incoming request is used to generate a unique key to throttle against.
The allowed request rate is determined from one of the following (in order of preference).
AnonRateThrottle is suitable if you want to restrict the rate of requests from unknown sources.
The UserRateThrottle will throttle users to a given rate of requests across the API. The user id is used to generate a unique key to throttle against. Unauthenticated requests will fall back to using the IP address of the incoming request to generate a unique key to throttle against.
The allowed request rate is determined from one of the following (in order of preference).
An API may have multiple UserRateThrottles in place at the same time. To do so, override UserRateThrottle and set a unique "scope" for each class.
For example, multiple user throttle rates could be implemented by using the following classes...
...and the following settings.
UserRateThrottle is suitable if you want simple global rate restrictions per-user.
The ScopedRateThrottle class can be used to restrict access to specific parts of the API. This throttle will only be applied if the view that is being accessed includes a .throttle_scope property. The unique throttle key will then be formed by concatenating the "scope" of the request with the unique user id or IP address.
The allowed request rate is determined by the DEFAULT_THROTTLE_RATES setting using a key from the request "scope".
For example, given the following views...
...and the following settings.
User requests to either ContactListView or ContactDetailView would be restricted to a total of 1000 requests per-day. User requests to UploadView would be restricted to 20 requests per day.
To create a custom throttle, override BaseThrottle and implement .allow_request(self, request, view). The method should return True if the request should be allowed, and False otherwise.
Optionally you may also override the .wait() method. If implemented, .wait() should return a recommended number of seconds to wait before attempting the next request, or None. The .wait() method will only be called if .allow_request() has previously returned False.
If the .wait() method is implemented and the request is throttled, then a Retry-After header will be included in the response.
The following is an example of a rate throttle, that will randomly throttle 1 in every 10 requests.
throttling.py


Each field in a Form class is responsible not only for validating data, but also for "cleaning" it — normalizing it to a consistent format.
— Django documentation
Serializer fields handle converting between primitive values and internal datatypes. They also deal with validating input values, as well as retrieving and setting the values from their parent objects.
Note: The serializer fields are declared in fields.py, but by convention you should import them using from rest_framework import serializers and refer to fields as serializers.<FieldName>.
Each serializer field class constructor takes at least these arguments. Some Field classes take additional, field-specific arguments, but the following should always be accepted:
Read-only fields are included in the API output, but should not be included in the input during create or update operations. Any 'read_only' fields that are incorrectly included in the serializer input will be ignored.
Set this to True to ensure that the field is used when serializing a representation, but is not used when creating or updating an instance during deserialization.
Defaults to False
Set this to True to ensure that the field may be used when updating or creating an instance, but is not included when serializing the representation.
Defaults to False
Normally an error will be raised if a field is not supplied during deserialization. Set to false if this field is not required to be present during deserialization.
Setting this to False also allows the object attribute or dictionary key to be omitted from output when serializing the instance. If the key is not present it will simply not be included in the output representation.
Defaults to True.
If set, this gives the default value that will be used for the field if no input value is supplied. If not set the default behaviour is to not populate the attribute at all.
The default is not applied during partial update operations. In the partial update case only fields that are provided in the incoming data will have a validated value returned.
May be set to a function or other callable, in which case the value will be evaluated each time it is used. When called, it will receive no arguments. If the callable has a requires_context = True attribute, then the serializer field will be passed as an argument.
For example:
When serializing the instance, default will be used if the object attribute or dictionary key is not present in the instance.
Note that setting a default value implies that the field is not required. Including both the default and required keyword arguments is invalid and will raise an error.
Normally an error will be raised if None is passed to a serializer field. Set this keyword argument to True if None should be considered a valid value.
Note that, without an explicit default, setting this argument to True will imply a default value of null for serialization output, but does not imply a default for input deserialization.
Defaults to False
The name of the attribute that will be used to populate the field. May be a method that only takes a self argument, such as URLField(source='get_absolute_url'), or may use dotted notation to traverse attributes, such as EmailField(source='user.email'). When serializing fields with dotted notation, it may be necessary to provide a default value if any object is not present or is empty during attribute traversal.
The value source='*' has a special meaning, and is used to indicate that the entire object should be passed through to the field. This can be useful for creating nested representations, or for fields which require access to the complete object in order to determine the output representation.
Defaults to the name of the field.
A list of validator functions which should be applied to the incoming field input, and which either raise a validation error or simply return. Validator functions should typically raise serializers.ValidationError, but Django's built-in ValidationError is also supported for compatibility with validators defined in the Django codebase or third party Django packages.
A dictionary of error codes to error messages.
A short text string that may be used as the name of the field in HTML form fields or other descriptive elements.
A text string that may be used as a description of the field in HTML form fields or other descriptive elements.
A value that should be used for pre-populating the value of HTML form fields. You may pass a callable to it, just as you may do with any regular Django Field:
A dictionary of key-value pairs that can be used to control how renderers should render the field.
Two examples here are 'input_type' and 'base_template':
For more details see the HTML & Forms documentation.
A boolean representation.
When using HTML encoded form input be aware that omitting a value will always be treated as setting a field to False, even if it has a default=True 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.
Note that Django 2.1 removed the blank kwarg from models.BooleanField. Prior to Django 2.1 models.BooleanField fields were always blank=True. Thus since Django 2.1 default serializers.BooleanField instances will be generated without the required kwarg (i.e. equivalent to required=True) whereas with previous versions of Django, default BooleanField instances will be generated with a required=False option. If you want to control this behaviour manually, explicitly declare the BooleanField on the serializer class, or use the extra_kwargs option to set the required flag.
Corresponds to django.db.models.fields.BooleanField.
Signature: BooleanField()
A boolean representation that also accepts None as a valid value.
Corresponds to django.db.models.fields.NullBooleanField.
Signature: NullBooleanField()
A text representation. Optionally validates the text to be shorter than max_length and longer than min_length.
Corresponds to django.db.models.fields.CharField or django.db.models.fields.TextField.
Signature: CharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True)
The allow_null option is also available for string fields, although its usage is discouraged in favor of allow_blank. It is valid to set both allow_blank=True and allow_null=True, but doing so means that there will be two differing types of empty value permissible for string representations, which can lead to data inconsistencies and subtle application bugs.
A text representation, validates the text to be a valid e-mail address.
Corresponds to django.db.models.fields.EmailField
Signature: EmailField(max_length=None, min_length=None, allow_blank=False)
A text representation, that validates the given value matches against a certain regular expression.
Corresponds to django.forms.fields.RegexField.
Signature: RegexField(regex, max_length=None, min_length=None, allow_blank=False)
The mandatory regex argument may either be a string, or a compiled python regular expression object.
Uses Django's django.core.validators.RegexValidator for validation.
A RegexField that validates the input against the pattern [a-zA-Z0-9_-]+.
Corresponds to django.db.models.fields.SlugField.
Signature: SlugField(max_length=50, min_length=None, allow_blank=False)
A RegexField that validates the input against a URL matching pattern. Expects fully qualified URLs of the form http://<host>/<path>.
Corresponds to django.db.models.fields.URLField. Uses Django's django.core.validators.URLValidator for validation.
Signature: URLField(max_length=200, min_length=None, allow_blank=False)
A field that ensures the input is a valid UUID string. The to_internal_value method will return a uuid.UUID instance. On output the field will return a string in the canonical hyphenated format, for example:
Signature: UUIDField(format='hex_verbose')
A field whose choices are limited to the filenames in a certain directory on the filesystem
Corresponds to django.forms.fields.FilePathField.
Signature: FilePathField(path, match=None, recursive=False, allow_files=True, allow_folders=False, required=None, **kwargs)
A field that ensures the input is a valid IPv4 or IPv6 string.
Corresponds to django.forms.fields.IPAddressField and django.forms.fields.GenericIPAddressField.
Signature: IPAddressField(protocol='both', unpack_ipv4=False, **options)
An integer representation.
Corresponds to django.db.models.fields.IntegerField, django.db.models.fields.SmallIntegerField, django.db.models.fields.PositiveIntegerField and django.db.models.fields.PositiveSmallIntegerField.
Signature: IntegerField(max_value=None, min_value=None)
A floating point representation.
Corresponds to django.db.models.fields.FloatField.
Signature: FloatField(max_value=None, min_value=None)
A decimal representation, represented in Python by a Decimal instance.
Corresponds to django.db.models.fields.DecimalField.
Signature: DecimalField(max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None)
To validate numbers up to 999 with a resolution of 2 decimal places, you would use:
And to validate numbers up to anything less than one billion with a resolution of 10 decimal places:
This field also takes an optional argument, coerce_to_string. If set to True the representation will be output as a string. If set to False the representation will be left as a Decimal instance and the final representation will be determined by the renderer.
If unset, this will default to the same value as the COERCE_DECIMAL_TO_STRING setting, which is True unless set otherwise.
A date and time representation.
Corresponds to django.db.models.fields.DateTimeField.
Signature: DateTimeField(format=api_settings.DATETIME_FORMAT, input_formats=None, default_timezone=None)
Format strings may either be Python strftime formats which explicitly specify the format, or the special string 'iso-8601', which indicates that ISO 8601 style datetimes should be used. (eg '2013-01-29T12:34:56.000000Z')
When a value of None is used for the format datetime objects will be returned by to_representation and the final output representation will determined by the renderer class.
When using ModelSerializer or HyperlinkedModelSerializer, note that any model fields with auto_now=True or auto_now_add=True will use serializer fields that are read_only=True by default.
If you want to override this behavior, you'll need to declare the DateTimeField explicitly on the serializer. For example:
A date representation.
Corresponds to django.db.models.fields.DateField
Signature: DateField(format=api_settings.DATE_FORMAT, input_formats=None)
Format strings may either be Python strftime formats which explicitly specify the format, or the special string 'iso-8601', which indicates that ISO 8601 style dates should be used. (eg '2013-01-29')
A time representation.
Corresponds to django.db.models.fields.TimeField
Signature: TimeField(format=api_settings.TIME_FORMAT, input_formats=None)
Format strings may either be Python strftime formats which explicitly specify the format, or the special string 'iso-8601', which indicates that ISO 8601 style times should be used. (eg '12:34:56.000000')
A Duration representation. Corresponds to django.db.models.fields.DurationField
The validated_data for these fields will contain a datetime.timedelta instance. The representation is a string following this format '[DD] [HH:[MM:]]ss[.uuuuuu]'.
Signature: DurationField(max_value=None, min_value=None)
A field that can accept a value out of a limited set of choices.
Used by ModelSerializer to automatically generate fields if the corresponding model field includes a choices=… argument.
Signature: ChoiceField(choices)
Both the allow_blank and allow_null are valid options on ChoiceField, although it is highly recommended that you only use one and not both. allow_blank should be preferred for textual choices, and allow_null should be preferred for numeric or other non-textual choices.
A field that can accept a set of zero, one or many values, chosen from a limited set of choices. Takes a single mandatory argument. to_internal_value returns a set containing the selected values.
Signature: MultipleChoiceField(choices)
As with ChoiceField, both the allow_blank and allow_null options are valid, although it is highly recommended that you only use one and not both. allow_blank should be preferred for textual choices, and allow_null should be preferred for numeric or other non-textual choices.
The FileField and ImageField classes are only suitable for use with MultiPartParser or FileUploadParser. Most parsers, such as e.g. JSON don't support file uploads. Django's regular FILE_UPLOAD_HANDLERS are used for handling uploaded files.
A file representation. Performs Django's standard FileField validation.
Corresponds to django.forms.fields.FileField.
Signature: FileField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)
An image representation. Validates the uploaded file content as matching a known image format.
Corresponds to django.forms.fields.ImageField.
Signature: ImageField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)
Requires either the Pillow package or PIL package. The Pillow package is recommended, as PIL is no longer actively maintained.
A field class that validates a list of objects.
Signature: ListField(child=<A_FIELD_INSTANCE>, allow_empty=True, min_length=None, max_length=None)
For example, to validate a list of integers you might use something like the following:
The ListField class also supports a declarative style that allows you to write reusable list field classes.
We can now reuse our custom StringListField class throughout our application, without having to provide a child argument to it.
A field class that validates a dictionary of objects. The keys in DictField are always assumed to be string values.
Signature: DictField(child=<A_FIELD_INSTANCE>, allow_empty=True)
For example, to create a field that validates a mapping of strings to strings, you would write something like this:
You can also use the declarative style, as with ListField. For example:
A preconfigured DictField that is compatible with Django's postgres HStoreField.
Signature: HStoreField(child=<A_FIELD_INSTANCE>, allow_empty=True)
Note that the child field must be an instance of CharField, as the hstore extension stores values as strings.
A field class that validates that the incoming data structure consists of valid JSON primitives. In its alternate binary mode, it will represent and validate JSON-encoded binary strings.
Signature: JSONField(binary, encoder)
A field class that simply returns the value of the field without modification.
This field is used by default with ModelSerializer when including field names that relate to an attribute rather than a model field.
Signature: ReadOnlyField()
For example, if has_expired was a property on the Account model, then the following serializer would automatically generate it as a ReadOnlyField:
A field class that does not take a value based on user input, but instead takes its value from a default value or callable.
Signature: HiddenField()
For example, to include a field that always provides the current time as part of the serializer validated data, you would use the following:
The HiddenField class is usually only needed if you have some validation that needs to run based on some pre-provided field values, but you do not want to expose all of those fields to the end user.
For further examples on HiddenField see the validators documentation.
A generic field that can be tied to any arbitrary model field. The ModelField class delegates the task of serialization/deserialization to its associated model field. This field can be used to create serializer fields for custom model fields, without having to create a new custom serializer field.
This field is used by ModelSerializer to correspond to custom model field classes.
Signature: ModelField(model_field=<Django ModelField instance>)
The ModelField class is generally intended for internal use, but can be used by your API if needed. In order to properly instantiate a ModelField, it must be passed a field that is attached to an instantiated model. For example: ModelField(model_field=MyModel()._meta.get_field('custom_field'))
This is a read-only field. It gets its value by calling a method on the serializer class it is attached to. It can be used to add any sort of data to the serialized representation of your object.
Signature: SerializerMethodField(method_name=None)
The serializer method referred to by the method_name argument should accept a single argument (in addition to self), which is the object being serialized. It should return whatever you want to be included in the serialized representation of the object. For example:
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.
Let's look at an example of serializing a class that represents an RGB color value:
By default field values are treated as mapping to an attribute on the object. If you need to customize how the field value is accessed and set you need to override .get_attribute() and/or .get_value().
As an example, let's create a field that can be used to represent the class name of the object being serialized:
Our ColorField class above currently does not perform any data validation. To indicate invalid data, we should raise a serializers.ValidationError, like so:
The .fail() method is a shortcut for raising ValidationError that takes a message string from the error_messages dictionary. For example:
This style keeps your error messages cleaner and more separated from your code, and should be preferred.
Here we'll take an example of a flat DataPoint model with x_coordinate and y_coordinate attributes.
Using a custom field and source='*' we can provide a nested representation of the coordinate pair:
Note that this example doesn't handle validation. Partly for that reason, in a real project, the coordinate nesting might be better handled with a nested serializer using source='*', with two IntegerField instances, each with their own source pointing to the relevant field.
The key points from the example, though, are:
to_representation is passed the entire DataPoint object and must map from that to the desired output.
Unless our field is to be read-only, to_internal_value must map back to a dict suitable for updating our target object. With source='*', the return from to_internal_value will update the root validated data dictionary, rather than a single key.
For completeness lets do the same thing again but with the nested serializer approach suggested above:
Here the mapping between the target and source attribute pairs (x and x_coordinate, y and y_coordinate) is handled in the IntegerField declarations. It's our NestedCoordinateSerializer that takes source='*'.
Our new DataPointSerializer exhibits the same behaviour as the custom field approach.
Serializing:
Deserializing:
But we also get the built-in validation for free:
For this reason, the nested serializer approach would be the first to try. You would use the custom field approach when the nested serializer becomes infeasible or overly complex.
The following third party packages are also available.
The drf-compound-fields package provides "compound" serializer fields, such as lists of simple values, which can be described by other fields rather than serializers with the many=True option. Also provided are fields for typed dictionaries and values that can be either a specific type or a list of items of that type.
The drf-extra-fields package provides extra serializer fields for REST framework, including Base64ImageField and PointField classes.
the djangorestframework-recursive package provides a RecursiveField for serializing and deserializing recursive structures
The django-rest-framework-gis package provides geographic addons for django rest framework like a GeometryField field and a GeoJSON serializer.
The django-rest-framework-hstore package provides an HStoreField to support django-hstore DictionaryField model field.
fields.py


Auth needs to be pluggable.
— Jacob Kaplan-Moss, "REST worst practices"
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 permission and throttling policies can then use those credentials to determine if the request should be permitted.
REST framework provides several authentication schemes out of the box, and also allows you to implement custom schemes.
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.
The request.user property will typically be set to an instance of the contrib.auth package's User class.
The request.auth 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.
Note: Don't forget that authentication by itself won't allow or disallow an incoming request, it simply identifies the credentials that the request was made with.
For information on how to set up the permission policies for your API please see the permissions documentation.
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 request.user and request.auth using the return value of the first class that successfully authenticates.
If no class authenticates, request.user will be set to an instance of django.contrib.auth.models.AnonymousUser, and request.auth will be set to None.
The value of request.user and request.auth for unauthenticated requests can be modified using the UNAUTHENTICATED_USER and UNAUTHENTICATED_TOKEN settings.
The default authentication schemes may be set globally, using the DEFAULT_AUTHENTICATION_CLASSES setting. For example.
You can also set the authentication scheme on a per-view or per-viewset basis, using the APIView class-based views.
Or, if you're using the @api_view decorator with function based views.
When an unauthenticated request is denied permission there are two different error codes that may be appropriate.
HTTP 401 responses must always include a WWW-Authenticate header, that instructs the client how to authenticate. HTTP 403 responses do not include the WWW-Authenticate header.
The kind of response that will be used depends on the authentication scheme. Although multiple authentication schemes may be in use, only one scheme may be used to determine the type of response. The first authentication class set on the view is used when determining the type of response.
Note that when a request may successfully authenticate, but still be denied permission to perform the request, in which case a 403 Permission Denied response will always be used, regardless of the authentication scheme.
Note that if deploying to Apache using mod_wsgi, the authorization header is not passed through to a WSGI application by default, as it is assumed that authentication will be handled by Apache, rather than at an application level.
If you are deploying to Apache, and using any non-session based authentication, you will need to explicitly configure mod_wsgi to pass the required headers through to the application. This can be done by specifying the WSGIPassAuthorization directive in the appropriate context and setting it to 'On'.
This authentication scheme uses HTTP Basic Authentication, signed against a user's username and password. Basic authentication is generally only appropriate for testing.
If successfully authenticated, BasicAuthentication provides the following credentials.
Unauthenticated responses that are denied permission will result in an HTTP 401 Unauthorized response with an appropriate WWW-Authenticate header. For example:
Note: If you use BasicAuthentication in production you must ensure that your API is only available over https. You should also ensure that your API clients will always re-request the username and password at login, and will never store those details to persistent storage.
This authentication scheme uses a simple token-based HTTP Authentication scheme. Token authentication is appropriate for client-server setups, such as native desktop and mobile clients.
To use the TokenAuthentication scheme you'll need to configure the authentication classes to include TokenAuthentication, and additionally include rest_framework.authtoken in your INSTALLED_APPS setting:
Note: Make sure to run manage.py migrate after changing your settings. The rest_framework.authtoken app provides Django database migrations.
You'll also need to create tokens for your users.
For clients to authenticate, the token key should be included in the Authorization HTTP header. The key should be prefixed by the string literal "Token", with whitespace separating the two strings. For example:
Note: If you want to use a different keyword in the header, such as Bearer, simply subclass TokenAuthentication and set the keyword class variable.
If successfully authenticated, TokenAuthentication provides the following credentials.
Unauthenticated responses that are denied permission will result in an HTTP 401 Unauthorized response with an appropriate WWW-Authenticate header. For example:
The curl command line tool may be useful for testing token authenticated APIs. For example:
Note: If you use TokenAuthentication in production you must ensure that your API is only available over https.
If you want every user to have an automatically generated Token, you can simply catch the User's post_save signal.
Note that you'll want to ensure you place this code snippet in an installed models.py module, or some other location that will be imported by Django on startup.
If you've already created some users, you can generate tokens for all existing users like this:
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 behaviour. To use it, add the obtain_auth_token view to your URLconf:
Note that the URL part of the pattern can be whatever you want to use.
The obtain_auth_token view will return a JSON response when valid username and password fields are POSTed to the view using form data or JSON:
Note that the default obtain_auth_token view explicitly uses JSON requests and responses, rather than using default renderer and parser classes in your settings.
By default, there are no permissions or throttling applied to the obtain_auth_token view. If you do wish to apply to throttle you'll need to override the view class, and include them using the throttle_classes attribute.
If you need a customized version of the obtain_auth_token view, you can do so by subclassing the ObtainAuthToken view class, and using that in your url conf instead.
For example, you may return additional user information beyond the token value:
And in your urls.py:
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 TokenAdmin class customize it to your needs, more specifically by declaring the user field as raw_field.
your_app/admin.py:
Since version 3.6.4 it's possible to generate a user token using the following command:
this command will return the API token for the given user, creating it if it doesn't exist:
In case you want to regenerate the token (for example if it has been compromised or leaked) you can pass an additional parameter:
This authentication scheme uses Django's default session backend for authentication. Session authentication is appropriate for AJAX clients that are running in the same session context as your website.
If successfully authenticated, SessionAuthentication provides the following credentials.
Unauthenticated responses that are denied permission will result in an HTTP 403 Forbidden response.
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 PUT, PATCH, POST or DELETE requests. See the Django CSRF documentation for more details.
Warning: Always use Django's standard login view when creating login pages. This will ensure your login views are properly protected.
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.
This authentication scheme allows you to delegate authentication to your web server, which sets the REMOTE_USER environment variable.
To use it, you must have django.contrib.auth.backends.RemoteUserBackend (or a subclass) in your AUTHENTICATION_BACKENDS setting. By default, RemoteUserBackend creates User objects for usernames that don't already exist. To change this and other behaviour, consult the Django documentation.
If successfully authenticated, RemoteUserAuthentication provides the following credentials:
Consult your web server's documentation for information about configuring an authentication method, e.g.:
To implement a custom authentication scheme, subclass BaseAuthentication and override the .authenticate(self, request) method. The method should return a two-tuple of (user, auth) if authentication succeeds, or None otherwise.
In some circumstances instead of returning None, you may want to raise an AuthenticationFailed exception from the .authenticate() method.
Typically the approach you should take is:
You may also override the .authenticate_header(self, request) method. If implemented, it should return a string that will be used as the value of the WWW-Authenticate header in a HTTP 401 Unauthorized response.
If the .authenticate_header() method is not overridden, the authentication scheme will return HTTP 403 Forbidden responses when an unauthenticated request is denied access.
Note: When your custom authenticator is invoked by the request object's .user or .auth properties, you may see an AttributeError re-raised as a WrappedAttributeError. This is necessary to prevent the original exception from being suppressed by the outer property access. Python will not recognize that the AttributeError originates from your custom authenticator and will instead assume that the request object does not have a .user or .auth property. These errors should be fixed or otherwise handled by your authenticator.
The following example will authenticate any incoming request as the user given by the username in a custom request header named 'X-USERNAME'.
The following third-party packages are also available.
The Django OAuth Toolkit package provides OAuth 2.0 support and works with Python 3.4+. The package is maintained by jazzband and uses the excellent OAuthLib. The package is well documented, and well supported and is currently our recommended package for OAuth 2.0 support.
Install using pip.
Add the package to your INSTALLED_APPS and modify your REST framework settings.
For more details see the Django REST framework - Getting started documentation.
The Django REST framework OAuth package provides both OAuth1 and OAuth2 support for REST framework.
This package was previously included directly in the REST framework but is now supported and maintained as a third-party package.
Install the package using pip.
For details on configuration and usage see the Django REST framework OAuth documentation for authentication and permissions.
JSON Web Token is a fairly new standard which can be used for token-based authentication. Unlike the built-in TokenAuthentication scheme, JWT Authentication doesn't need to use a database to validate a token. A package for JWT authentication is djangorestframework-simplejwt which provides some features as well as a pluggable token blacklist app.
The HawkREST library builds on the Mohawk library to let you work with Hawk signed requests and responses in your API. Hawk lets two parties securely communicate with each other using messages signed by a shared key. It is based on HTTP MAC access authentication (which was based on parts of OAuth 1.0).
HTTP Signature (currently a IETF draft) provides a way to achieve origin authentication and message integrity for HTTP messages. Similar to Amazon's HTTP Signature scheme, used by many of its services, it permits stateless, per-request authentication. Elvio Toccalino maintains the djangorestframework-httpsignature (outdated) package which provides an easy to use HTTP Signature Authentication mechanism. You can use the updated fork version of djangorestframework-httpsignature, which is drf-httpsig.
Djoser 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.
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.
There are currently two forks of this project.
Django-rest-framework-social-oauth2 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.
Django-rest-knox 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).
drfpasswordless 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.
django-rest-authemail 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.
Django-Rest-Durin 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.
More information can be found in the Documentation.
authentication.py


Validators can be useful for re-using validation logic between different types of fields.
— Django documentation
Most of the time you're dealing with validation in REST framework you'll simply be relying on the default field validation, or writing explicit validation methods on serializer or field classes.
However, sometimes you'll want to place your validation logic into reusable components, so that it can easily be reused throughout your codebase. This can be achieved by using validator functions and validator classes.
Validation in Django REST framework serializers is handled a little differently to how validation works in Django's ModelForm class.
With ModelForm the validation is performed partially on the form, and partially on the model instance. With REST framework the validation is performed entirely on the serializer class. This is advantageous for the following reasons:
When you're using ModelSerializer all of this is handled automatically for you. If you want to drop down to using Serializer classes instead, then you need to define the validation rules explicitly.
As an example of how REST framework uses explicit validation, we'll take a simple model class that has a field with a uniqueness constraint.
Here's a basic ModelSerializer that we can use for creating or updating instances of CustomerReportRecord:
If we open up the Django shell using manage.py shell we can now
The interesting bit here is the reference field. We can see that the uniqueness constraint is being explicitly enforced by a validator on the serializer field.
Because of this more explicit style REST framework includes a few validator classes that are not available in core Django. These classes are detailed below.
This validator can be used to enforce the unique=True constraint on model fields. It takes a single required argument, and an optional messages argument:
This validator should be applied to serializer fields, like so:
This validator can be used to enforce unique_together constraints on model instances. It has two required arguments, and a single optional messages argument:
The validator should be applied to serializer classes, like so:
Note: The UniqueTogetherValidator class always imposes an implicit constraint that all the fields it applies to are always treated as required. Fields with default values are an exception to this as they always supply a value even when omitted from user input.
These validators can be used to enforce the unique_for_date, unique_for_month and unique_for_year constraints on model instances. They take the following arguments:
The validator should be applied to serializer classes, like so:
The date field that is used for the validation is always required to be present on the serializer class. You can't simply rely on a model class default=..., because the value being used for the default wouldn't be generated until after the validation has run.
There are a couple of styles you may want to use for this depending on how you want your API to behave. If you're using ModelSerializer you'll probably simply rely on the defaults that REST framework generates for you, but if you are using Serializer or simply want more explicit control, use on of the styles demonstrated below.
If you want the date field to be writable the only thing worth noting is that you should ensure that it is always available in the input data, either by setting a default argument, or by setting required=True.
If you want the date field to be visible, but not editable by the user, then set read_only=True and additionally set a default=... argument.
If you want the date field to be entirely hidden from the user, then use HiddenField. This field type does not accept user input, but instead always returns its default value to the validated_data in the serializer.
Note: The UniqueFor<Range>Validator classes impose an implicit constraint that the fields they are applied to are always treated as required. Fields with default values are an exception to this as they always supply a value even when omitted from user input.
Validators that are applied across multiple fields in the serializer can sometimes require a field input that should not be provided by the API client, but that is available as input to the validator.
Two patterns that you may want to use for this sort of validation include:
REST framework includes a couple of defaults that may be useful in this context.
A default class that can be used to represent the current user. In order to use this, the 'request' must have been provided as part of the context dictionary when instantiating the serializer.
A default class that can be used to only set a default argument during create operations. During updates the field is omitted.
It takes a single argument, which is the default value or callable that should be used during create operations.
There are some ambiguous cases where you'll need to instead handle validation explicitly, rather than relying on the default serializer classes that ModelSerializer generates.
In these cases you may want to disable the automatically generated validators, by specifying an empty list for the serializer Meta.validators attribute.
By default "unique together" validation enforces that all fields be required=True. In some cases, you might want to explicit apply required=False to one of the fields, in which case the desired behaviour of the validation is ambiguous.
In this case you will typically need to exclude the validator from the serializer class, and instead write any validation logic explicitly, either in the .validate() method, or else in the view.
For example:
When applying an update to an existing instance, uniqueness validators will exclude the current instance from the uniqueness check. The current instance is available in the context of the uniqueness check, because it exists as an attribute on the serializer, having initially been passed using instance=... when instantiating the serializer.
In the case of update operations on nested serializers there's no way of applying this exclusion, because the instance is not available.
Again, you'll probably want to explicitly remove the validator from the serializer class, and write the code for the validation constraint explicitly, in a .validate() method, or in the view.
If you're not sure exactly what behavior a ModelSerializer class will generate it is usually a good idea to run manage.py shell, and print an instance of the serializer, so that you can inspect the fields and validators that it automatically generates for you.
Also keep in mind that with complex cases it can often be better to explicitly define your serializer classes, rather than relying on the default ModelSerializer behavior. This involves a little more code, but ensures that the resulting behavior is more transparent.
You can use any of Django's existing validators, or write your own custom validators.
A validator may be any callable that raises a serializers.ValidationError on failure.
You can specify custom field-level validation by adding .validate_<field_name> methods to your Serializer subclass. This is documented in the Serializer docs
To write a class-based validator, use the __call__ method. Class-based validators are useful as they allow you to parameterize and reuse behavior.
In some advanced cases you might want a validator to be passed the serializer field it is being used with as additional context. You can do so by setting a requires_context = True attribute on the validator. The __call__ method will then be called with the serializer_field or serializer as an additional argument.
validators.py