Validation¶
New in version 2.12.
django-jsonform supports basic data validation by default and appropriate error messages are displayed below the input fields in case any value is invalid.
Validation keywords¶
For array
type¶
Keyword |
Description |
---|---|
|
(Integer) Minimum number or required items. |
|
(Integer) Maximum number of allowed items. |
|
(Boolean) Whether all items must be unique or not. |
For object
type¶
Keyword |
Description |
---|---|
|
(List) A list containing names of required object properties (keys). |
Changed in version 2.16.0: Support for required
keyword for object properties was added.
For string
type¶
Keyword |
Description |
---|---|
|
(Boolean) Whether this field is required or not. |
|
(Integer) Minimum length of the value. |
|
(Integer) Maximum allowed length of the value. |
For integer
and number
type¶
Keyword |
Description |
---|---|
|
(Boolean) Whether this field is required or not. |
|
(Integer/Float) Minimum allowed value including this limit. |
|
(Integer/Float) Maximum allowed value including this limit. |
|
(Integer/Float) Minimum allowed value excluding this limit. |
|
(Integer/Float) Maximum allowed value excluding this limit. |
For boolean
type¶
Keyword |
Description |
---|---|
|
(Boolean) Whether this field is required or not. |
Example¶
# Schema
{
'type': 'array',
'minItems': 1,
'items': {
'type': 'object',
'properties': {
'name': {
'type': 'string',
'required': True,
'maxLength': 30
},
'age': {
'type': 'integer',
'minimum': '18'
}
}
}
}
Custom validation¶
There are many ways to validate a field in Django.
Two of the most basic ways are either by using the Model.clean()
method or by
passing a validators
argument to the model field.
The problem with these validation methods is that there is no way to provide error messages for particular input fields.
The error message you return will be displayed above the JSON form widget.
Basic validation¶
Model.clean()
: Refer to Django docs on using Model.clean() method.validators
: Refer Django docs on using Validators.
Advanced validation¶
Advanced validation allows you to provide error messages for each input field which will be displayed right below them.
Creating a form¶
For this, you’re required to create a custom form class for the admin page.
# models.py
class ShoppingList(models.Model):
items = JSONField(schema=...)
...
# admin.py
class ShoppingListForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# set your validators on the form field
self.fields['items'].validators = [items_validator]
class ShoppingListAdmin(admin.ModelAdmin):
form = ShoppingListForm
Writing the validator¶
In your validator function, instead of raising ValidationError
you must raise JSONSchemaValidationError
. This exception allows you to pass
error messages for individual input field in the widget.
We’ll use the ErrorMap
helper class to create
the mapping of field names to error messages:
from django_jsonform.exceptions import JSONSchemaValidationError
from django_jsonform.utils import ErrorMap
def items_validator(value):
error_map = ErrorMap()
if value[0] != 'Banana':
error_map.set(coords=[0], msg='First item in shopping list must be Banana')
if value[1] != 'Eggs':
error_map.set(coords=[1], msg='Second item in shopping list must be Eggs')
# do other validations ...
if error_map:
# if error_map has keys raise error
raise JSONSchemaValidationError(
'Please correct errors below',
error_map=error_map # pass error_map to exception
)
For passing multiple error messages for one input, use a list:
# using ErrorMap.set()
error_map.set(coords=[0], msg=['First error', 'Second error', ...])
# or useing ErrorMap.append()
error_map.append(coords=[0], msg=['First error', 'Second error', ...])
See ErrorMap
class’s docs for more details on its
usage.
Providing errors for deeply nested inputs¶
The keys in the error_map
dict are “coordinates” of the invalid input fields
(see Coordinates page to learn more).
For example, if each shopping list item has a name
and a quantity
and you want
to display an error message under the first item’s quantity
input, you’ll do this:
from django_jsonform.utils import ErrorMap
error_map = ErrorMap()
# error message for 'quantity' of '0' (first item)
error_map.set(coords=[0, 'quantity'], msg='Minimum quantity must be 5')
Validating data in the browser before form submission¶
The JavaScript part of this widget supports optional in-browser validation.
The data will be validated before the form is submitted. If there are any errors, the form will not submit and user will be asked to correct them.
This method only supports basic validation. When the data has passed the browser validation tests, it will be validated once again on the server with your custom validation rules.
To enable in-browser validation, set the validate_on_submit
attribute to
True
on the widget.
There are two ways to do this:
Option 1: Changing the attribute on the widget:
# Option 1: In form's __init__ method
class ShoppingListForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['items'].widget.validate_on_submit = True
Option 2: Alternatively, if you’re overriding the widget in the Meta
class,
you can pass the validate_on_submit
argument to the widget:
# Option 2: In form's Meta class
class ShoppingListForm(forms.ModelForm):
class Meta:
widgets: {
'items': JSONFormWidget(schema=..., validate_on_submit=True)
}
Built-in validators¶
JSONSchemaValidator
¶
-
class
JSONSchemaValidator
(schema)¶
New in version 2.12.
This is the default validator used for validating the submitted forms.
Parameters:
-
schema
: dict¶ Schema to use for validation.
Methods:
-
validate
(data)¶ Validates the
data
against the schema provided to the validator instance.If the data is invalid, it will raise
JSONSchemaValidationError
exception.
Usage:
from django_jsonform.validators import JSONSchemaValidator
# create a validator instance
validator = JSONSchemaValidator(schema=...)
# validate the data
validate(data)
# if the data is invalid, JSONSchemaValidationError will be raised