Skip to content
Snippets Groups Projects
Commit c336d4d3 authored by Nik | Klampfradler's avatar Nik | Klampfradler
Browse files

Document jsonschema.py with some fixes

parent 54cebe0b
Branches main
No related tags found
No related merge requests found
from typing import Optional
from django import forms
from django_forms_as_jsonschema.layout import _Section
from .layout import _Section
class JSONSchema:
"""Encapsulation of a JSON form schema."""
def __init__(self):
self.schema = {
......@@ -14,6 +17,8 @@ class JSONSchema:
@staticmethod
def generate_field(field):
"""Generate schema for one form field."""
# Defaults for a generic field
new_field = {
"type": "string",
"title": str(field.label or ""),
......@@ -22,63 +27,43 @@ class JSONSchema:
"required": field.required,
}
# string, number, integer, boolean.
if type(field.widget) == forms.TextInput:
# Inspect field and update schema accordingly
if isinstance(field.widget, forms.TextInput):
new_field["type"] = "string"
elif type(field.widget) == forms.NumberInput:
new_field["type"] = "integer" if type(field) == forms.IntegerField else "number"
elif type(field.widget) == forms.EmailInput:
elif isinstance(field.widget, forms.NumberInput) and isinstance(field, forms.IntegerField):
new_field["type"] = "integer"
elif isinstance(field.widget, forms.NumberInput):
new_field["type"] = "number"
elif isinstance(field.widget, forms.EmailInput):
new_field["type"] = "string"
new_field["format"] = "email"
elif type(field.widget) == forms.URLInput:
elif isinstance(field.widget, forms.URLInput):
new_field["type"] = "string"
new_field["format"] = "url"
elif type(field.widget) == forms.PasswordInput:
elif isinstance(field.widget, forms.PasswordInput):
new_field["type"] = "string"
new_field["format"] = "password"
new_field["x-display"] = "password"
elif type(field.widget) == forms.HiddenInput:
elif isinstance(field.widget, forms.HiddenInput):
new_field["type"] = "string"
new_field["format"] = "hidden"
elif type(field.widget) == forms.MultipleHiddenInput:
...
elif type(field.widget) in [forms.FileInput, forms.ClearableFileInput]:
new_field |= {
"type": "string",
"contentMediaType": "image/*" if type(field) == forms.ImageField else "*",
"writeOnly": True
}
# Fixme: differentiate between clearable and non-clearable
# elif type(field.widget) == forms.ClearableFileInput:
# ...
elif type(field.widget) == forms.Textarea:
elif isinstance(field.widget, forms.FileInput):
new_field["type"] = "string"
new_field["contentMediaType"] = "image/*" if isinstance(field, forms.ImageField) else "*"
new_field["writeOnly"] = True
elif isinstance(field.widget, forms.Textarea):
new_field["x-display"] = "textarea"
elif type(field.widget) == forms.DateInput:
elif isinstance(field.widget, forms.DateInput):
new_field["type"] = "string"
new_field["format"] = "date"
elif type(field.widget) == forms.DateTimeInput:
elif isinstance(field.widget, forms.DateTimeInput):
new_field["type"] = "string"
new_field["format"] = "date-time"
elif type(field.widget) == forms.TimeInput:
elif isinstance(field.widget, forms.TimeInput):
new_field["type"] = "string"
new_field["format"] = "time"
elif type(field.widget) == forms.CheckboxInput:
elif isinstance(field.widget, forms.CheckboxInput):
new_field["type"] = "boolean"
elif type(field.widget) in [forms.Select, forms.SelectMultiple, forms.RadioSelect, forms.CheckboxSelectMultiple,
forms.NullBooleanSelect]:
one_of = []
......@@ -95,26 +80,17 @@ class JSONSchema:
new_field["type"] = "string"
new_field["oneOf"] = one_of
if type(field.widget) == forms.RadioSelect:
if isinstance(field.widget, forms.RadioSelect):
new_field["x-display"] = "radio"
elif type(field.widget) == forms.CheckboxSelectMultiple:
elif isinstance(field.widget, forms.CheckboxSelectMultiple):
new_field["x-display"] = "checkbox"
elif type(field.widget) == forms.SplitDateTimeWidget:
...
elif type(field.widget) == forms.SplitHiddenDateTimeWidget:
...
elif type(field.widget) == forms.SelectDateWidget:
...
else:
print("[Django-forms-as-jsonschema] Unsupported field/widget detected: ")
print(f"{field=}, {type(field)=}, {type(field.widget)=}")
raise TypeError(f"Unsupported field/widget: {repr(field)}, {repr(field.widget)}")
return new_field
def add_field(self, name, field, metadata: dict = None):
def add_field(self, name, field, metadata: Optional[dict] = None):
"""Add a form field to this schema."""
new_field = self.generate_field(field)
if metadata and metadata.get("section_name") and self.schema["properties"].get(
metadata["section_name"]
......@@ -127,6 +103,7 @@ class JSONSchema:
@staticmethod
def generate_section(section: _Section):
"""Generate schema for a form section."""
sec = {
"title": section.title,
"type": "object",
......@@ -139,7 +116,9 @@ class JSONSchema:
return sec
def add_section(self, section: _Section):
"""Add a form section to this schema."""
self.schema["properties"][section.codename] = self.generate_section(section)
def update_properties(self, props: dict):
"""Merge new property values into schema properties."""
self.schema["properties"].update(props)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment