Build nested, server-validated JSON editors from JSON Schema using ordinary
Django Field, Widget, Form, and ModelForm primitives.
django-native-jsonform is intended for applications that store configurable
data in models.JSONField but still want Django's validation, permissions,
widgets, templates, admin integration, and extension points.
- Objects, arrays, nested arrays, choices, local
$ref, and discriminatedoneOfbranches. - Native Django fields and server-side validation—no client-only JSON editor.
- Independent Draft 2020-12 document validation, including composition, conditionals, tuple arrays, dynamic properties and registered references.
- Replaceable native JSON editors for structures without generated child widgets.
- Dynamic schemas with access to the current request, user, object, and form.
- Exact-path,
*, and**overrides for fields, widgets, attributes, serializers, defaults, permissions, and templates. - Cloneable registries for project-specific JSON formats and widgets.
- Sparse JSON preservation: displayed defaults do not have to be persisted.
- Unknown-key preservation for forward-compatible and permission-aware forms.
- Template-driven rendering and small progressive-enhancement JavaScript.
python -m pip install django-native-jsonformINSTALLED_APPS = [
# ...
"django_native_jsonform",
]from django import forms
from django_native_jsonform import JSONSchemaFormField, JSONSchemaModelForm
from .models import Product
PRODUCT_SCHEMA = {
"type": "object",
"properties": {
"title": {"type": "string", "title": "Title"},
"price": {"type": "number", "minimum": 0},
"tags": {
"type": "array",
"items": {"type": "string"},
},
},
"required": ["title"],
}
class ProductForm(JSONSchemaModelForm):
metadata = JSONSchemaFormField(schema=PRODUCT_SCHEMA, required=False)
class Meta:
model = Product
fields = "__all__"For Django admin, add JSONSchemaAdminMixin so callable schemas and factories
receive the current request context:
from django.contrib import admin
from django_native_jsonform import JSONSchemaAdminMixin
@admin.register(Product)
class ProductAdmin(JSONSchemaAdminMixin, admin.ModelAdmin):
form = ProductFormfrom django import forms
from django_native_jsonform import FieldFactoryContext, default_registry
registry = default_registry.clone()
@registry.register_field("string", format="media-asset")
def media_asset_field(context: FieldFactoryContext) -> forms.Field:
return MediaAssetField(
user=context.form_context.user,
schema=context.schema,
required=context.required,
)
class ProductForm(JSONSchemaModelForm):
metadata = JSONSchemaFormField(schema=PRODUCT_SCHEMA, registry=registry)The package does not depend on a particular rich text editor, media library, autocomplete implementation, or design system. Those are registered by each consumer.
The complete wiki lives in docs/ and is published at
barcelona-dev.github.io/django-native-jsonform.
Start with the quick start, then see customization and building extensions.
The API is currently alpha. It was extracted from a production Django
application, but semantic-versioning compatibility begins with 1.0.
MIT
Generate serializers from your JSON Schema using
django_native_jsonform.rest_framework.serializer_from_schema, or attach
JSONSchemaField to a model serializer's JSON attribute. Install the drf or
jsonapi extra. Opt-in json_api=True converts nested keys using the project's
JSON:API formatting configuration while keeping schema validation in one place.
See the DRF integration guide
for PATCH semantics, references and examples.