Versioning an interface is just a "polite" way to kill deployed clients.
— Roy Fielding.
API versioning allows you to alter behavior between different clients. REST framework provides for a number of different versioning schemes.
Versioning is determined by the incoming client request, and may either be based on the request URL, or based on the request headers.
There are a number of valid approaches to approaching versioning. Non-versioned systems can also be appropriate, particularly if you're engineering for very long-term systems with multiple clients outside of your control.
When API versioning is enabled, the request.version attribute will contain a string that corresponds to the version requested in the incoming client request.
By default, versioning is not enabled, and request.version will always return None.
How you vary the API behavior is up to you, but one example you might typically want is to switch to a different serialization style in a newer version. For example:
The reverse function included by REST framework ties in with the versioning scheme. You need to make sure to include the current request as a keyword argument, like so.
The above function will apply any URL transformations appropriate to the request version. For example:
When using hyperlinked serialization styles together with a URL based versioning scheme make sure to include the request as context to the serializer.
Doing so will allow any returned URLs to include the appropriate versioning.
The versioning scheme is defined by the DEFAULT_VERSIONING_CLASS settings key.
Unless it is explicitly set, the value for DEFAULT_VERSIONING_CLASS will be None. In this case the request.version attribute will always return None.
You can also set the versioning scheme on an individual view. Typically you won't need to do this, as it makes more sense to have a single versioning scheme used globally. If you do need to do so, use the versioning_class attribute.
The following settings keys are also used to control versioning:
You can also set your versioning class plus those three values on a per-view or a per-viewset basis by defining your own versioning scheme and using the default_version, allowed_versions and version_param class variables. For example, if you want to use URLPathVersioning:
This scheme requires the client to specify the version as part of the media type in the Accept header. The version is included as a media type parameter, that supplements the main media type.
Here's an example HTTP request using the accept header versioning style.
In the example request above request.version attribute would return the string '1.0'.
Versioning based on accept headers is generally considered as best practice, although other styles may be suitable depending on your client requirements.
Strictly speaking the json media type is not specified as including additional parameters. If you are building a well-specified public API you might consider using a vendor media type. To do so, configure your renderers to use a JSON based renderer with a custom media type:
Your client requests would now look like this:
This scheme requires the client to specify the version as part of the URL path.
Your URL conf must include a pattern that matches the version with a 'version' keyword argument, so that this information is available to the versioning scheme.
To the client, this scheme is the same as URLPathVersioning. The only difference is how it is configured in your Django application, as it uses URL namespacing, instead of URL keyword arguments.
With this scheme the request.version attribute is determined based on the namespace that matches the incoming request path.
In the following example we're giving a set of views two different possible URL prefixes, each under a different namespace:
Both URLPathVersioning and NamespaceVersioning are reasonable if you just need a simple versioning scheme. The URLPathVersioning approach might be better suitable for small ad-hoc projects, and the NamespaceVersioning is probably easier to manage for larger projects.
The hostname versioning scheme requires the client to specify the requested version as part of the hostname in the URL.
For example the following is an HTTP request to the http://v1.example.com/bookings/ URL:
By default this implementation expects the hostname to match this simple regular expression:
Note that the first group is enclosed in brackets, indicating that this is the matched portion of the hostname.
The HostNameVersioning scheme can be awkward to use in debug mode as you will typically be accessing a raw IP address such as 127.0.0.1. There are various online tutorials on how to access localhost with a custom subdomain which you may find helpful in this case.
Hostname based versioning can be particularly useful if you have requirements to route incoming requests to different servers based on the version, as you can configure different DNS records for different API versions.
This scheme is a simple style that includes the version as a query parameter in the URL. For example:
To implement a custom versioning scheme, subclass BaseVersioning and override the .determine_version method.
The following example uses a custom X-API-Version header to determine the requested version.
If your versioning scheme is based on the request URL, you will also want to alter how versioned URLs are determined. In order to do so you should override the .reverse() method on the class. See the source code for examples.
versioning.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


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


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


Expanding the usefulness of the serializers is something that we would like to address. However, it's not a trivial problem, and it will take some serious design work.
— Russell Keith-Magee, Django users group
Serializers allow complex data such as querysets and model instances to be converted to native Python datatypes that can then be easily rendered into JSON, XML or other content types. Serializers also provide deserialization, allowing parsed data to be converted back into complex types, after first validating the incoming data.
The serializers in REST framework work very similarly to Django's Form and ModelForm classes. We provide a Serializer class which gives you a powerful, generic way to control the output of your responses, as well as a ModelSerializer class which provides a useful shortcut for creating serializers that deal with model instances and querysets.
Let's start by creating a simple object we can use for example purposes:
We'll declare a serializer that we can use to serialize and deserialize data that corresponds to Comment objects.
Declaring a serializer looks very similar to declaring a form:
We can now use CommentSerializer to serialize a comment, or list of comments. Again, using the Serializer class looks a lot like using a Form class.
At this point we've translated the model instance into Python native datatypes. To finalise the serialization process we render the data into json.
Deserialization is similar. First we parse a stream into Python native datatypes...
...then we restore those native datatypes into a dictionary of validated data.
If we want to be able to return complete object instances based on the validated data we need to implement one or both of the .create() and .update() methods. For example:
If your object instances correspond to Django models you'll also want to ensure that these methods save the object to the database. For example, if Comment was a Django model, the methods might look like this:
Now when deserializing data, we can call .save() to return an object instance, based on the validated data.
Calling .save() will either create a new instance, or update an existing instance, depending on if an existing instance was passed when instantiating the serializer class:
Both the .create() and .update() methods are optional. You can implement either neither, one, or both of them, depending on the use-case for your serializer class.
Sometimes you'll want your view code to be able to inject additional data at the point of saving the instance. This additional data might include information like the current user, the current time, or anything else that is not part of the request data.
You can do so by including additional keyword arguments when calling .save(). For example:
Any additional keyword arguments will be included in the validated_data argument when .create() or .update() are called.
In some cases the .create() and .update() method names may not be meaningful. For example, in a contact form we may not be creating new instances, but instead sending an email or other message.
In these cases you might instead choose to override .save() directly, as being more readable and meaningful.
For example:
Note that in the case above we're now having to access the serializer .validated_data property directly.
When deserializing data, you always need to call is_valid() before attempting to access the validated data, or save an object instance. If any validation errors occur, the .errors property will contain a dictionary representing the resulting error messages. For example:
Each key in the dictionary will be the field name, and the values will be lists of strings of any error messages corresponding to that field. The non_field_errors key may also be present, and will list any general validation errors. The name of the non_field_errors key may be customized using the NON_FIELD_ERRORS_KEY REST framework setting.
When deserializing a list of items, errors will be returned as a list of dictionaries representing each of the deserialized items.
The .is_valid() method takes an optional raise_exception flag that will cause it to raise a serializers.ValidationError exception if there are validation errors.
These exceptions are automatically dealt with by the default exception handler that REST framework provides, and will return HTTP 400 Bad Request responses by default.
You can specify custom field-level validation by adding .validate_<field_name> methods to your Serializer subclass. These are similar to the .clean_<field_name> methods on Django forms.
These methods take a single argument, which is the field value that requires validation.
Your validate_<field_name> methods should return the validated value or raise a serializers.ValidationError. For example:
Note: If your <field_name> is declared on your serializer with the parameter required=False then this validation step will not take place if the field is not included.
To do any other validation that requires access to multiple fields, add a method called .validate() to your Serializer subclass. This method takes a single argument, which is a dictionary of field values. It should raise a serializers.ValidationError if necessary, or just return the validated values. For example:
Individual fields on a serializer can include validators, by declaring them on the field instance, for example:
Serializer classes can also include reusable validators that are applied to the complete set of field data. These validators are included by declaring them on an inner Meta class, like so:
For more information see the validators documentation.
When passing an initial object or queryset to a serializer instance, the object will be made available as .instance. If no initial object is passed then the .instance attribute will be None.
When passing data to a serializer instance, the unmodified data will be made available as .initial_data. If the data keyword argument is not passed then the .initial_data attribute will not exist.
By default, serializers must be passed values for all required fields or they will raise validation errors. You can use the partial argument in order to allow partial updates.
The previous examples are fine for dealing with objects that only have simple datatypes, but sometimes we also need to be able to represent more complex objects, where some of the attributes of an object might not be simple datatypes such as strings, dates or integers.
The Serializer class is itself a type of Field, and can be used to represent relationships where one object type is nested inside another.
If a nested representation may optionally accept the None value you should pass the required=False flag to the nested serializer.
Similarly if a nested representation should be a list of items, you should pass the many=True flag to the nested serializer.
When dealing with nested representations that support deserializing the data, any errors with nested objects will be nested under the field name of the nested object.
Similarly, the .validated_data property will include nested data structures.
If you're supporting writable nested representations you'll need to write .create() or .update() methods that handle saving multiple objects.
The following example demonstrates how you might handle creating a user with a nested profile object.
For updates you'll want to think carefully about how to handle updates to relationships. For example if the data for the relationship is None, or not provided, which of the following should occur?
Here's an example for an .update() method on our previous UserSerializer class.
Because the behavior of nested creates and updates can be ambiguous, and may require complex dependencies between related models, REST framework 3 requires you to always write these methods explicitly. The default ModelSerializer .create() and .update() methods do not include support for writable nested representations.
There are however, third-party packages available such as DRF Writable Nested that support automatic writable nested representations.
An alternative to saving multiple related instances in the serializer is to write custom model manager classes that handle creating the correct instances.
For example, suppose we wanted to ensure that User instances and Profile instances are always created together as a pair. We might write a custom manager class that looks something like this:
This manager class now more nicely encapsulates that user instances and profile instances are always created at the same time. Our .create() method on the serializer class can now be re-written to use the new manager method.
For more details on this approach see the Django documentation on model managers, and this blogpost on using model and manager classes.
The Serializer class can also handle serializing or deserializing lists of objects.
To serialize a queryset or list of objects instead of a single object instance, you should pass the many=True flag when instantiating the serializer. You can then pass a queryset or list of objects to be serialized.
The default behavior for deserializing multiple objects is to support multiple object creation, but not support multiple object updates. For more information on how to support or customize either of these cases, see the ListSerializer documentation below.
There are some cases where you need to provide extra context to the serializer in addition to the object being serialized. One common case is if you're using a serializer that includes hyperlinked relations, which requires the serializer to have access to the current request so that it can properly generate fully qualified URLs.
You can provide arbitrary additional context by passing a context argument when instantiating the serializer. For example:
The context dictionary can be used within any serializer field logic, such as a custom .to_representation() method, by accessing the self.context attribute.
Often you'll want serializer classes that map closely to Django model definitions.
The ModelSerializer class provides a shortcut that lets you automatically create a Serializer class with fields that correspond to the Model fields.
The ModelSerializer class is the same as a regular Serializer class, except that:
Declaring a ModelSerializer looks like this:
By default, all the model fields on the class will be mapped to a corresponding serializer fields.
Any relationships such as foreign keys on the model will be mapped to PrimaryKeyRelatedField. Reverse relationships are not included by default unless explicitly included as specified in the serializer relations documentation.
Serializer classes generate helpful verbose representation strings, that allow you to fully inspect the state of their fields. This is particularly useful when working with ModelSerializers where you want to determine what set of fields and validators are being automatically created for you.
To do so, open the Django shell, using python manage.py shell, then import the serializer class, instantiate it, and print the object representation…
If you only want a subset of the default fields to be used in a model serializer, you can do so using fields or exclude options, just as you would with a ModelForm. It is strongly recommended that you explicitly set all fields that should be serialized using the fields attribute. This will make it less likely to result in unintentionally exposing data when your models change.
For example:
You can also set the fields attribute to the special value '__all__' to indicate that all fields in the model should be used.
For example:
You can set the exclude attribute to a list of fields to be excluded from the serializer.
For example:
In the example above, if the Account model had 3 fields account_name, users, and created, this will result in the fields account_name and created to be serialized.
The names in the fields and exclude attributes will normally map to model fields on the model class.
Alternatively names in the fields options can map to properties or methods which take no arguments that exist on the model class.
Since version 3.3.0, it is mandatory to provide one of the attributes fields or exclude.
The default ModelSerializer uses primary keys for relationships, but you can also easily generate nested representations using the depth option:
The depth option should be set to an integer value that indicates the depth of relationships that should be traversed before reverting to a flat representation.
If you want to customize the way the serialization is done you'll need to define the field yourself.
You can add extra fields to a ModelSerializer or override the default fields by declaring fields on the class, just as you would for a Serializer class.
Extra fields can correspond to any property or callable on the model.
You may wish to specify multiple fields as read-only. Instead of adding each field explicitly with the read_only=True attribute, you may use the shortcut Meta option, read_only_fields.
This option should be a list or tuple of field names, and is declared as follows:
Model fields which have editable=False set, and AutoField fields will be set to read-only by default, and do not need to be added to the read_only_fields option.
Note: There is a special-case where a read-only field is part of a unique_together constraint at the model level. In this case the field is required by the serializer class in order to validate the constraint, but should also not be editable by the user.
The right way to deal with this is to specify the field explicitly on the serializer, providing both the read_only=True and default=… keyword arguments.
One example of this is a read-only relation to the currently authenticated User which is unique_together with another identifier. In this case you would declare the user field like so:
Please review the Validators Documentation for details on the UniqueTogetherValidator and CurrentUserDefault classes.
There is also a shortcut allowing you to specify arbitrary additional keyword arguments on fields, using the extra_kwargs option. As in the case of read_only_fields, this means you do not need to explicitly declare the field on the serializer.
This option is a dictionary, mapping field names to a dictionary of keyword arguments. For example:
Please keep in mind that, if the field has already been explicitly declared on the serializer class, then the extra_kwargs option will be ignored.
When serializing model instances, there are a number of different ways you might choose to represent relationships. The default representation for ModelSerializer is to use the primary keys of the related instances.
Alternative representations include serializing using hyperlinks, serializing complete nested representations, or serializing with a custom representation.
For full details see the serializer relations documentation.
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 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.
This property should be the serializer field class, that is used for relational fields by default.
For ModelSerializer this defaults to PrimaryKeyRelatedField.
For HyperlinkedModelSerializer this defaults to serializers.HyperlinkedRelatedField.
The serializer field class that should be used for any url field on the serializer.
Defaults to serializers.HyperlinkedIdentityField
The serializer field class that should be used for any choice fields on the serializer.
Defaults to serializers.ChoiceField
The following methods are called to determine the class and keyword arguments for each field that should be automatically included on the serializer. Each of these methods should return a two tuple of (field_class, field_kwargs).
Called to generate a serializer field that maps to a standard model field.
The default implementation returns a serializer class based on the serializer_field_mapping attribute.
Called to generate a serializer field that maps to a relational model field.
The default implementation returns a serializer class based on the serializer_related_field attribute.
The relation_info argument is a named tuple, that contains model_field, related_model, to_many and has_through_model properties.
Called to generate a serializer field that maps to a relational model field, when the depth option has been set.
The default implementation dynamically creates a nested serializer class based on either ModelSerializer or HyperlinkedModelSerializer.
The nested_depth will be the value of the depth option, minus one.
The relation_info argument is a named tuple, that contains model_field, related_model, to_many and has_through_model properties.
Called to generate a serializer field that maps to a property or zero-argument method on the model class.
The default implementation returns a ReadOnlyField class.
Called to generate a serializer field for the serializer's own url field. The default implementation returns a HyperlinkedIdentityField class.
Called when the field name did not map to any model field or model property. The default implementation raises an error, although subclasses may customize this behavior.
The HyperlinkedModelSerializer class is similar to the ModelSerializer class except that it uses hyperlinks to represent relationships, rather than primary keys.
By default the serializer will include a url field instead of a primary key field.
The url field will be represented using a HyperlinkedIdentityField serializer field, and any relationships on the model will be represented using a HyperlinkedRelatedField serializer field.
You can explicitly include the primary key by adding it to the fields option, for example:
When instantiating a HyperlinkedModelSerializer you must include the current request in the serializer context, for example:
Doing so will ensure that the hyperlinks can include an appropriate hostname, so that the resulting representation uses fully qualified URLs, such as:
Rather than relative URLs, such as:
If you do want to use relative URLs, you should explicitly pass {'request': None} in the serializer context.
There needs to be a way of determining which views should be used for hyperlinking to model instances.
By default hyperlinks are expected to correspond to a view name that matches the style '{model_name}-detail', and looks up the instance by a pk keyword argument.
You can override a URL field view name and lookup field by using either, or both of, the view_name and lookup_field options in the extra_kwargs setting, like so:
Alternatively you can set the fields on the serializer explicitly. For example:
Tip: Properly matching together hyperlinked representations and your URL conf can sometimes be a bit fiddly. Printing the repr of a HyperlinkedModelSerializer instance is a particularly useful way to inspect exactly which view names and lookup fields the relationships are expected to map too.
The name of the URL field defaults to 'url'. You can override this globally, by using the URL_FIELD_NAME setting.
The ListSerializer class provides the behavior for serializing and validating multiple objects at once. You won't typically need to use ListSerializer directly, but should instead simply pass many=True when instantiating a serializer.
When a serializer is instantiated and many=True is passed, a ListSerializer instance will be created. The serializer class then becomes a child of the parent ListSerializer
The following argument can also be passed to a ListSerializer field or a serializer that is passed many=True:
This is True by default, but can be set to False if you want to disallow empty lists as valid input.
There are a few use cases when you might want to customize the ListSerializer behavior. For example:
For these cases you can modify the class that is used when many=True is passed, by using the list_serializer_class option on the serializer Meta class.
For example:
The default implementation for multiple object creation is to simply call .create() for each item in the list. If you want to customize this behavior, you'll need to customize the .create() method on ListSerializer class that is used when many=True is passed.
For example:
By default the ListSerializer class does not support multiple updates. This is because the behavior that should be expected for insertions and deletions is ambiguous.
To support multiple updates you'll need to do so explicitly. When writing your multiple update code make sure to keep the following in mind:
You will need to add an explicit id field to the instance serializer. The default implicitly-generated id field is marked as read_only. This causes it to be removed on updates. Once you declare it explicitly, it will be available in the list serializer's update method.
Here's an example of how you might choose to implement multiple updates:
It is possible that a third party package may be included alongside the 3.1 release that provides some automatic support for multiple update operations, similar to the allow_add_remove behavior that was present in REST framework 2.
When a serializer with many=True is instantiated, we need to determine which arguments and keyword arguments should be passed to the .__init__() method for both the child Serializer class, and for the parent ListSerializer class.
The default implementation is to pass all arguments to both classes, except for validators, and any custom keyword arguments, both of which are assumed to be intended for the child serializer class.
Occasionally you might need to explicitly specify how the child and parent classes should be instantiated when many=True is passed. You can do so by using the many_init class method.
BaseSerializer class that can be used to easily support alternative serialization and deserialization styles.
This class implements the same basic API as the Serializer class:
There are four methods that can be overridden, depending on what functionality you want the serializer class to support:
Because this class provides the same interface as the Serializer class, you can use it with the existing generic class-based views exactly as you would for a regular Serializer or ModelSerializer.
The only difference you'll notice when doing so is the BaseSerializer classes will not generate HTML forms in the browsable API. This is because the data they return does not include all the field information that would allow each field to be rendered into a suitable HTML input.
To implement a read-only serializer using the BaseSerializer class, we just need to override the .to_representation() method. Let's take a look at an example using a simple Django model:
It's simple to create a read-only serializer for converting HighScore instances into primitive data types.
We can now use this class to serialize single HighScore instances:
Or use it to serialize multiple instances:
To create a read-write serializer we first need to implement a .to_internal_value() method. This method returns the validated values that will be used to construct the object instance, and may raise a serializers.ValidationError if the supplied data is in an incorrect format.
Once you've implemented .to_internal_value(), the basic validation API will be available on the serializer, and you will be able to use .is_valid(), .validated_data and .errors.
If you want to also support .save() you'll need to also implement either or both of the .create() and .update() methods.
Here's a complete example of our previous HighScoreSerializer, that's been updated to support both read and write operations.
The BaseSerializer class is also useful if you want to implement new generic serializer classes for dealing with particular serialization styles, or for integrating with alternative storage backends.
The following class is an example of a generic serializer that can handle coercing arbitrary objects into primitive representations.
If you need to alter the serialization or deserialization behavior of a serializer class, you can do so by overriding the .to_representation() or .to_internal_value() methods.
Some reasons this might be useful include...
The signatures for these methods are as follows:
Takes the object instance that requires serialization, and should return a primitive representation. Typically this means returning a structure of built-in Python datatypes. The exact types that can be handled will depend on the render classes you have configured for your API.
May be overridden in order to modify the representation style. For example:
Takes the unvalidated incoming data as input and should return the validated data that will be made available as serializer.validated_data. The return value will also be passed to the .create() or .update() methods if .save() is called on the serializer class.
If any of the validation fails, then the method should raise a serializers.ValidationError(errors). The errors argument should be a dictionary mapping field names (or settings.NON_FIELD_ERRORS_KEY) to a list of error messages. If you don't need to alter deserialization behavior and instead want to provide object-level validation, it's recommended that you instead override the .validate() method.
The data argument passed to this method will normally be the value of request.data, so the datatype it provides will depend on the parser classes you have configured for your API.
Similar to Django forms, you can extend and reuse serializers through inheritance. This allows you to declare a common set of fields or methods on a parent class that can then be used in a number of serializers. For example,
Like Django's Model and ModelForm classes, the inner Meta class on serializers does not implicitly inherit from it's parents' inner Meta classes. If you want the Meta class to inherit from a parent class you must do so explicitly. For example:
Typically we would recommend not using inheritance on inner Meta classes, but instead declaring all options explicitly.
Additionally, the following caveats apply to serializer inheritance:
It’s possible to declaratively remove a Field inherited from a parent class by setting the name to be None on the subclass.
However, you can only use this technique to opt out from a field defined declaratively by a parent class; it won’t prevent the ModelSerializer from generating a default field. To opt-out from default fields, see Specifying which fields to include.
Once a serializer has been initialized, the dictionary of fields that are set on the serializer may be accessed using the .fields attribute. Accessing and modifying this attribute allows you to dynamically modify the serializer.
Modifying the fields argument directly allows you to do interesting things such as changing the arguments on serializer fields at runtime, rather than at the point of declaring the serializer.
For example, if you wanted to be able to set which fields should be used by a serializer at the point of initializing it, you could create a serializer class like so:
This would then allow you to do the following:
REST framework 2 provided an API to allow developers to override how a ModelSerializer class would automatically generate the default set of fields.
This API included the .get_field(), .get_pk_field() and other methods.
Because the serializers have been fundamentally redesigned with 3.0 this API no longer exists. You can still modify the fields that get created but you'll need to refer to the source code, and be aware that if the changes you make are against private bits of API then they may be subject to change.
The following third party packages are also available.
The django-rest-marshmallow package provides an alternative implementation for serializers, using the python marshmallow library. It exposes the same API as the REST framework serializers, and can be used as a drop-in replacement in some use-cases.
The serpy package is an alternative implementation for serializers that is built for speed. Serpy serializes complex datatypes to simple native types. The native types can be easily converted to JSON or any other format needed.
The django-rest-framework-mongoengine package provides a MongoEngineModelSerializer serializer class that supports using MongoDB as the storage layer for Django REST framework.
The django-rest-framework-gis package provides a GeoFeatureModelSerializer serializer class that supports GeoJSON both for read and write operations.
The django-rest-framework-hstore package provides an HStoreSerializer to support django-hstore DictionaryField model field and its schema-mode feature.
The dynamic-rest package extends the ModelSerializer and ModelViewSet interfaces, adding API query parameters for filtering, sorting, and including / excluding all fields and relationships defined by your serializers.
The drf-dynamic-fields package provides a mixin to dynamically limit the fields per serializer to a subset specified by an URL parameter.
The drf-flex-fields package extends the ModelSerializer and ModelViewSet to provide commonly used functionality for dynamically setting fields and expanding primitive fields to nested models, both from URL parameters and your serializer class definitions.
The django-rest-framework-serializer-extensions package provides a collection of tools to DRY up your serializers, by allowing fields to be defined on a per-view/request basis. Fields can be whitelisted, blacklisted and child serializers can be optionally expanded.
The html-json-forms package provides an algorithm and serializer for processing <form> submissions per the (inactive) HTML JSON Form specification. The serializer facilitates processing of arbitrarily nested JSON structures within HTML. For example, <input name="items[0][id]" value="5"> will be interpreted as {"items": [{"id": "5"}]}.
DRF-Base64 provides a set of field and model serializers that handles the upload of base64-encoded files.
djangorestframework-queryfields allows API clients to specify which fields will be sent in the response via inclusion/exclusion query parameters.
The drf-writable-nested package provides writable nested model serializer which allows to create/update models with nested related data.
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.
serializers.py


Authentication or identification by itself is not usually sufficient to gain access to information or code. For that, the entity requesting access must have authorization.
— Apple Developer Documentation
Together with authentication and throttling, permissions determine whether a request should be granted or denied access.
Permission checks are always run at the very start of the view, before any other code is allowed to proceed. Permission checks will typically use the authentication information in the request.user and request.auth properties to determine if the incoming request should be permitted.
Permissions are used to grant or deny access for different classes of users to different parts of the API.
The simplest style of permission would be to allow access to any authenticated user, and deny access to any unauthenticated user. This corresponds to the IsAuthenticated class in REST framework.
A slightly less strict style of permission would be to allow full access to authenticated users, but allow read-only access to unauthenticated users. This corresponds to the IsAuthenticatedOrReadOnly class in REST framework.
Permissions in REST framework are always defined as a list of permission classes.
Before running the main body of the view each permission in the list is checked. If any permission check fails an exceptions.PermissionDenied or exceptions.NotAuthenticated exception will be raised, and the main body of the view will not run.
When the permissions checks fail either a "403 Forbidden" or a "401 Unauthorized" response will be returned, according to the following rules:
REST framework permissions also support object-level permissioning. Object level permissions are used to determine if a user should be allowed to act on a particular object, which will typically be a model instance.
Object level permissions are run by REST framework's generic views when .get_object() is called. As with view level permissions, an exceptions.PermissionDenied exception will be raised if the user is not allowed to act on the given object.
If you're writing your own views and want to enforce object level permissions, or if you override the get_object method on a generic view, then you'll need to explicitly call the .check_object_permissions(request, obj) method on the view at the point at which you've retrieved the object.
This will either raise a PermissionDenied or NotAuthenticated exception, or simply return if the view has the appropriate permissions.
For example:
Note: With the exception of DjangoObjectPermissions, the provided permission classes in rest_framework.permissions do not implement the methods necessary to check object permissions.
If you wish to use the provided permission classes in order to check object permissions, you must subclass them and implement the has_object_permission() method described in the Custom permissions section (below).
For performance reasons the generic views will not automatically apply object level permissions to each instance in a queryset when returning a list of objects.
Often when you're using object level permissions you'll also want to filter the queryset appropriately, to ensure that users only have visibility onto instances that they are permitted to view.
Because the get_object() method is not called, object level permissions from the has_object_permission() method are not applied when creating objects. In order to restrict object creation you need to implement the permission check either in your Serializer class or override the perform_create() method of your ViewSet class.
The default permission policy may be set globally, using the DEFAULT_PERMISSION_CLASSES setting. For example.
If not specified, this setting defaults to allowing unrestricted access:
You can also set the authentication policy 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.
Note: when you set new permission classes via the class attribute or decorators you're telling the view to ignore the default list set in the settings.py file.
Provided they inherit from rest_framework.permissions.BasePermission, permissions can be composed using standard Python bitwise operators. For example, IsAuthenticatedOrReadOnly could be written:
Note: it supports & (and), | (or) and ~ (not).
The AllowAny permission class will allow unrestricted access, regardless of if the request was authenticated or unauthenticated.
This permission is not strictly required, since you can achieve the same result by using an empty list or tuple for the permissions setting, but you may find it useful to specify this class because it makes the intention explicit.
The IsAuthenticated permission class will deny permission to any unauthenticated user, and allow permission otherwise.
This permission is suitable if you want your API to only be accessible to registered users.
The IsAdminUser permission class will deny permission to any user, unless user.is_staff is True in which case permission will be allowed.
This permission is suitable if you want your API to only be accessible to a subset of trusted administrators.
The IsAuthenticatedOrReadOnly will allow authenticated users to perform any request. Requests for unauthorised users will only be permitted if the request method is one of the "safe" methods; GET, HEAD or OPTIONS.
This permission is suitable if you want to your API to allow read permissions to anonymous users, and only allow write permissions to authenticated users.
This permission class ties into Django's standard django.contrib.auth model permissions. This permission must only be applied to views that have a .queryset property or get_queryset() method. Authorization will only be granted if the user is authenticated and has the relevant model permissions assigned.
The default behaviour can also be overridden to support custom model permissions. For example, you might want to include a view model permission for GET requests.
To use custom model permissions, override DjangoModelPermissions and set the .perms_map property. Refer to the source code for details.
Similar to DjangoModelPermissions, but also allows unauthenticated users to have read-only access to the API.
This permission class ties into Django's standard object permissions framework that allows per-object permissions on models. In order to use this permission class, you'll also need to add a permission backend that supports object-level permissions, such as django-guardian.
As with DjangoModelPermissions, this permission must only be applied to views that have a .queryset property or .get_queryset() method. Authorization will only be granted if the user is authenticated and has the relevant per-object permissions and relevant model permissions assigned.
Note that DjangoObjectPermissions does not require the django-guardian package, and should support other object-level backends equally well.
As with DjangoModelPermissions you can use custom model permissions by overriding DjangoObjectPermissions and setting the .perms_map property. Refer to the source code for details.
Note: If you need object level view permissions for GET, HEAD and OPTIONS requests and are using django-guardian for your object-level permissions backend, you'll want to consider using the DjangoObjectPermissionsFilter class provided by the djangorestframework-guardian package. It ensures that list endpoints only return results including objects for which the user has appropriate view permissions.
To implement a custom permission, override BasePermission and implement either, or both, of the following methods:
The methods should return True if the request should be granted access, and False otherwise.
If you need to test if a request is a read operation or a write operation, you should check the request method against the constant SAFE_METHODS, which is a tuple containing 'GET', 'OPTIONS' and 'HEAD'. For example:
Note: The instance-level has_object_permission method will only be called if the view-level has_permission checks have already passed. Also note that in order for the instance-level checks to run, the view code should explicitly call .check_object_permissions(request, obj). If you are using the generic views then this will be handled for you by default. (Function-based views will need to check object permissions explicitly, raising PermissionDenied on failure.)
Custom permissions will raise a PermissionDenied exception if the test fails. To change the error message associated with the exception, implement a message attribute directly on your custom permission. Otherwise the default_detail attribute from PermissionDenied will be used. Similarly, to change the code identifier associated with the exception, implement a code attribute directly on your custom permission - otherwise the default_code attribute from PermissionDenied will be used.
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.
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:
Note that the generic views will check the appropriate object level permissions, but if you're writing your own custom views, you'll need to make sure you check the object level permission checks yourself. You can do so by calling self.check_object_permissions(request, obj) from the view once you have the object instance. This call will raise an appropriate APIException if any object-level permission checks fail, and will otherwise simply return.
Also note that the generic views will only check the object-level permissions for views that retrieve a single model instance. If you require object-level filtering of list views, you'll need to filter the queryset separately. See the filtering documentation for more details.
REST framework offers three different methods to customize access restrictions on a case-by-case basis. These apply in different scenarios and have different effects and limitations.
The following table lists the access restriction methods and the level of control they offer over which actions.
* A Serializer class should not raise PermissionDenied in a list action, or the entire list would not be returned.  ** The get_*() methods have access to the current view and can return different Serializer or QuerySet instances based on the request or action.
The following third party packages are also available.
The Django REST - Access Policy package provides a way to define complex access rules in declarative policy classes that are attached to view sets or function-based views. The policies are defined in JSON in a format similar to AWS' Identity & Access Management policies.
The Composed Permissions package provides a simple way to define complex and multi-depth (with logic operators) permission objects, using small and reusable components.
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 Django Rest Framework Roles package makes it easier to parameterize your API over multiple types of users.
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 Role Filters package provides simple filtering over multiple types of roles.
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.
permissions.py


Machine interacting web services tend to use more structured formats for sending data than form-encoded, since they're sending more complex data than simple forms
— Malcom Tredinnick, Django developers group
REST framework includes a number of built in Parser classes, that allow you to accept requests with various media types. There is also support for defining your own custom parsers, which gives you the flexibility to design the media types that your API accepts.
The set of valid parsers for a view is always defined as a list of classes. When request.data is accessed, REST framework will examine the Content-Type header on the incoming request, and determine which parser to use to parse the request content.
Note: When developing client applications always remember to make sure you're setting the Content-Type header when sending data in an HTTP request.
If you don't set the content type, most clients will default to using 'application/x-www-form-urlencoded', which may not be what you wanted.
As an example, if you are sending json encoded data using jQuery with the .ajax() method, you should make sure to include the contentType: 'application/json' setting.
The default set of parsers may be set globally, using the DEFAULT_PARSER_CLASSES setting. For example, the following settings would allow only requests with JSON content, instead of the default of JSON or form data.
You can also set the parsers 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.
Parses JSON request content. request.data will be populated with a dictionary of data.
.media_type: application/json
Parses HTML form content. request.data will be populated with a QueryDict of data.
You will typically want to use both FormParser and MultiPartParser together in order to fully support HTML form data.
.media_type: application/x-www-form-urlencoded
Parses multipart HTML form content, which supports file uploads. Both request.data will be populated with a QueryDict.
You will typically want to use both FormParser and MultiPartParser together in order to fully support HTML form data.
.media_type: multipart/form-data
Parses raw file upload content. The request.data property will be a dictionary with a single key 'file' containing the uploaded file.
If the view used with FileUploadParser is called with a filename URL keyword argument, then that argument will be used as the filename.
If it is called without a filename URL keyword argument, then the client must set the filename in the Content-Disposition HTTP header. For example Content-Disposition: attachment; filename=upload.jpg.
.media_type: */*
To implement a custom parser, you should override BaseParser, set the .media_type property, and implement the .parse(self, stream, media_type, parser_context) method.
The method should return the data that will be used to populate the request.data property.
The arguments passed to .parse() are:
A stream-like object representing the body of the request.
Optional. If provided, this is the media type of the incoming request content.
Depending on the request's Content-Type: header, this may be more specific than the renderer's media_type attribute, and may include media type parameters. For example "text/plain; charset=utf-8".
Optional. If supplied, this argument will be a dictionary containing any additional context that may be required to parse the request content.
By default this will include the following keys: view, request, args, kwargs.
The following is an example plaintext parser that will populate the request.data property with a string representing the body of the request.
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.
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.
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.
parsers.py