django-jsonform currently implements a custom JSON Schema spec written specifically for Django.
You should also read the standard spec at https://json-schema.org.
At present, certain features from the standard spec are not supported by django-jsonform. However, we've also implemented a few extra features which are not in the standard spec.
For some complex schema examples, see Examples page <examples>
.
For data validation, see Validation page </guide/validation>
.
Currently, only these six types are supported:
A JSON array (similar to Python list).
Keywords:
Keyword | Description |
---|---|
items (required) |
Specifies the scheme for the items allowed in the list. |
title |
Specify a title for the list. |
default |
A list containing all the default initial values for the array. |
Validation </guide/validation>
keywords:
Keyword | Description |
---|---|
minItems (alias min_items ) |
Limit the minimum number of items in a list. |
maxItems (alias max_items ) |
Limit the maximum number of items in a list. |
uniqueItems |
Whether all items in the list must be unique or not. |
2.8 Support for setting initial array data using default
keyword was added.
2.12 Support for uniqueItems
keyword was added.
This example shows a schema of a list containing string items:
# Schema
{
'type': 'list', # or 'array'
'items': {
'type': 'string',
'default': 'Hello', # default value for new items
'readonly': True, # make all items readonly
},
'minItems': 1,
'maxItems': 5,
'default': ['One', 'Two', 'Three'], # initial value for the whole list
}
# Output data
['one', 'two', 'three', ...]
A JSON object (similar to Python dict).
Keywords:
Keyword | Description |
---|---|
properties (alias keys ) |
Specifies the keys (or fields) in a dict/object. |
additionalProperties |
Allow users to add extra keys not declared in the schema. |
title |
Specify a title for the dict. |
This example shows a schema of a basic dict:
# Schema
{
'type': 'dict': # or 'object'
'keys': { # or 'properties'
'name': {
'type': 'string'
},
'email': {
'type': 'string'
},
'age': {
'type': 'number',
'title': 'Age in years',
'default': 50, # default value for age
'readonly': True, # make it readonly
}
}
}
# Output data
{
'name': 'John Doe',
'email': 'john@example.com',
'age': 99
}
By default, an object's data can only contain keys declared in the schema. But you can allow users to add extra keys using the additionalProperties
keyword.
The additionalProperties
keyword can be:
- a schema. You can provide a sub-schema for the new properties.
- a boolean. As a shortcut for adding string keys only, you can set this to
True
. - a reference. You can also use the
$ref
keyword to reference and reuse existing schema. Seereferencing schema
docs below to learn more.
2.10 Support for sub-schema for new properties was added.
# Schema
{
'type': 'dict', # or 'object'
'keys': { # or 'properties'
'name': { 'type': 'string' },
},
'addtionalProperties': True
# or
'additionalProperties': { 'type': 'string' }
}
# Output data
{
'name': 'John Doe', # declared in the schema
'gender': 'Male', # added by the user
}
A string.
This can't be at the top level of the schema. If you only want to save a string, you should use Django's CharField
.
Keywords:
Keyword | Description |
---|---|
title |
Specify the label for the input field. |
|
Specify choices for the field. See the document on Choices <guide/choices> for more. |
|
Use this to specify the input field type. See inputs for string type for more. |
|
Use this to specify the input field type, such as a textarea. For most use cases, prefer the format keyword. |
default |
Specify a default value for this input field. |
readonly (alias readOnly ) |
Make this input field readonly. |
helpText (alias help_text ) |
Display a help text under this input. |
placeholder |
Placeholder text for this input. |
Validation </guide/validation>
keywords:
Keyword | Description |
---|---|
required |
Whether this field is required or not. |
minLength |
Minimum required length. |
maxLength |
Maximum allowed length. |
2.6 Support for default
and readonly
keywords was added.
2.9 Support for helpText
(or help_text
) keywords was added.
2.11 Support for placeholder
, enum
and handler
keywords was added.
2.12 Support for required
, minLength
and maxLength
keywords was added.
A number (including floats).
This can't be at the top level of the schema. If you only want to save a number, you should use Django's FloatField
.
It gets a number
HTML input by default. It can be overridden using the range
widget.
Keywords:
Keyword | Description |
---|---|
title |
Specify the label for the input field. |
|
Specify choices for the field. See the document on Choices <guide/choices> for more. |
widget |
Use this to specify the input field type, such as a range input. |
default |
Specify a default numerical value for this input field. |
readonly (alias readOnly ) |
Make this input field readonly. |
helpText (alias help_text ) |
Display a help text under this input. |
placeholder |
Placeholder text for this input. |
Validation </guide/validation>
keywords:
Keyword | Description |
---|---|
required |
Whether this field is required or not. |
minimum |
Minimum allowed value including this limit. |
maximum |
Maximum allowed value including this limit. |
exclusiveMinimum |
Minimum allowed value excluding this limit. |
exclusiveMaximum |
Maximum allowed value excluding this limit. |
2.6 Support for default
and readonly
keywords was added.
2.9 Support for helpText
(or help_text
) keywords was added.
2.11 Support for placeholder
and enum
keywords was added.
2.12 Support for required
, minimum
and maximum
, exclusiveMinimum
and exclusiveMaximum
keywords was added.
An integer.
This can't be at the top level of the schema. If you only want to save an integer, you should use Django's IntegerField
.
It gets a number
HTML input by default. It can be overridden using the range
widget.
Keywords:
Keyword | Description |
---|---|
title |
Specify the label for the input field. |
|
Specify choices for the field. See the document on Choices <guide/choices> for more. |
widget |
Use this to specify the input field type, such as a range input. |
default |
Specify a default numerical value for this input field. |
readonly (alias readOnly ) |
Make this input field readonly. |
helpText (alias help_text ) |
Display a help text under this input. |
placeholder |
Placeholder text for this input |
Validation </guide/validation>
keywords:
Keyword | Description |
---|---|
required |
Whether this field is required or not. |
minimum |
Minimum allowed value including this limit. |
maximum |
Maximum allowed value including this limit. |
exclusiveMinimum |
Minimum allowed value excluding this limit. |
exclusiveMaximum |
Maximum allowed value excluding this limit. |
2.6 Support for default
and readonly
keywords was added.
2.9 Support for helpText
(or help_text
) keywords was added.
2.11 Support for placeholder
and enum
keywords was added.
2.12 Support for required
, minimum
and maximum
, exclusiveMinimum
and exclusiveMaximum
keywords was added.
A boolean.
This can't be at the top level of the schema. If you only want to save an boolean, you should use Django's BooleanField
.
It gets a checkbox
HTML input by default. It can't be overridden.
Keywords:
Keyword | Description |
---|---|
title |
Specify the label for the input field. |
|
Specify choices for the field. See the document on Choices <guide/choices> for more. |
widget |
Use this to specify the input field type, such as a radio input. |
default |
Specify a default boolean value for this input field. |
readonly (alias readOnly ) |
Make this input field readonly. |
helpText (alias help_text ) |
Display a help text under this input. |
Validation </guide/validation>
keywords:
Keyword | Description |
---|---|
required |
Whether this field is required or not. |
2.6 Support for default
and readonly
keywords was added.
2.9 Support for helpText
(or help_text
) keywords was added.
2.12 Support for required
keyword was added.
2.10
JSON schema specification allows you to reference parts of schema for reuse in multiple places. This feature also allows you to recursively nest an object within itself.
Use the $ref
keyword to reference other parts of the schema.
In the following example, shipping_address
has same fields as billing_address
. So, instead of defining the schema twice, you can reference the earlier defined schema.
{
'type': 'object',
'properties': {
'billing_address': {
'type': 'object',
'properties': {
'street': { 'type': 'string' },
'city': { 'type': 'string' },
'state': { 'type': 'string' }
}
},
'shipping_address': { '$ref': '#/properties/billing_address' }
}
}
You can define common schema and keep them in a single place under the $defs
object:
{
'type': 'object',
'properties': {
'billing_address': {
'$ref': '#/$defs/address'
},
'shipping_address': {
'$ref': '#/$defs/address'
}
},
'$defs': {
'address': {
'type': 'object',
'properties': {
'street': { 'type': 'string' },
'city': { 'type': 'string' },
'state': { 'type': 'string' }
}
}
}
}
- Structuring a complex schema
Official documentation on referencing and nesting on JSON Schema's website
The $ref
keyword also makes recursion possible. You can use it for recursively nesting an object within itself.
For example, a Menu object can have link items and a sub-menu (dropdown menu) which contains more links and a sub-sub-menu and so on...
{
'type': 'array',
'title': 'Menu',
'items': {
'type': 'object',
'properties': {
'text': {
'type': 'string',
'title': 'Display text for the item'
},
'link': {
'type': 'string',
'title': 'URL of the item'
},
'children': { '$ref': '#' }
}
}
}
Caution
Beware of the infinite loop while referencing.
In certain cases, referencing ($ref
) may cause an infinite loop. Currently, that error is unhandled, and the widget will not be rendered at all if that happens.
One particular case is when two objects reference each other. For example, a
is a reference to b
and b
is a reference to a
.
There might be other cases, too. If the widget doesn't render while you're using $ref
, please open your browser's dev console to check the error message.
Also, open an issue on Github.
Infinite loop error handling will be improved in a future release.
These features are not supported by django-jsonform yet. These are planned to be added in future but there's no definite ETA:
- Validation
anyOf
/allOf
/oneOf