From b7e136716ecb183eeb4a86a252a371a615b7c299 Mon Sep 17 00:00:00 2001 From: Julian Leucker <leuckerj@gmail.com> Date: Wed, 31 Aug 2022 21:25:44 +0200 Subject: [PATCH] Create schemas automatically --- django_forms_as_jsonschema/forms.py | 7 +- django_forms_as_jsonschema/schema.py | 170 +++++++++++++++++++++++++++ 2 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 django_forms_as_jsonschema/schema.py diff --git a/django_forms_as_jsonschema/forms.py b/django_forms_as_jsonschema/forms.py index 976b257..0355f09 100644 --- a/django_forms_as_jsonschema/forms.py +++ b/django_forms_as_jsonschema/forms.py @@ -1,6 +1,11 @@ from django.forms import Form +from django_forms_as_jsonschema.schema import Schema + class JSONSchemaFormMixin: def as_jsonschema(self: Form) -> str: - pass + schema = Schema() + for name, field in self.fields.items(): + schema.add_field(name, field) + return schema.schema diff --git a/django_forms_as_jsonschema/schema.py b/django_forms_as_jsonschema/schema.py new file mode 100644 index 0000000..bb8761e --- /dev/null +++ b/django_forms_as_jsonschema/schema.py @@ -0,0 +1,170 @@ +import copy +import json + +from django import forms + + +class Schema: + SCHEMA = { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "properties": {}, + } + + def __init__(self): + self.schema = copy.deepcopy(self.SCHEMA) + + # example_json = { + # "type": "object", + # "properties": { + # "stringProp": { + # "type": "string", + # "title": "I'm a string", + # "description": "This description is used as a help message." + # }, + # "stringTextareaProp": { + # "type": "string", + # "title": "I'm a string in a textarea", + # "x-display": "textarea" + # }, + # "numberProp": { + # "type": "number", + # "title": "I'm a number" + # }, + # "integerProp": { + # "type": "integer", + # "title": "I'm an integer" + # }, + # "integerSliderProp": { + # "type": "integer", + # "title": "I'm an integer in a slider", + # "x-display": "slider", + # "minimum": 0, + # "maximum": 5 + # }, + # "booleanProp": { + # "type": "boolean", + # "title": "I'm a boolean", + # "description": "This description is used as a help message." + # }, + # "booleanSwitchProp": { + # "type": "boolean", + # "title": "I'm a boolean with switch display", + # "x-display": "switch", + # "description": "This description is used as a help message." + # }, + # "stringArrayProp": { + # "type": "array", + # "title": "I'm an array of strings", + # "items": { + # "type": "string" + # } + # }, + # "integerArrayProp": { + # "type": "array", + # "title": "I'm an array of integers", + # "items": { + # "type": "integer" + # } + # } + # } + # } + + def build(self): + return json.dumps(self.schema) + + def add_field(self, name, field): + type_ = "string" + format_ = None + x_display = None + enum = None + + # string, number, integer, boolean. + + match type(field.widget): + case forms.TextInput: + type_ = "string" + + case forms.NumberInput: + type_ = "number" + + case forms.EmailInput: + type_ = "string" + format_ = "email" + + case forms.URLInput: + type_ = "string" + format_ = "url" + + case forms.PasswordInput: + type_ = "string" + format_ = "password" + x_display = "password" + + case forms.HiddenInput: + type_ = "string" + format_ = "hidden" + + case forms.MultipleHiddenInput: + ... + + case forms.FileInput: + ... + + case forms.ClearableFileInput: + ... + + case forms.Textarea: + x_display = "textarea" + + case forms.DateInput: + type_ = "string" + format_ = "date" + + case forms.DateTimeInput: + type_ = "string" + format_ = "date-time" + + case forms.TimeInput: + type_ = "string" + format_ = "time" + + case forms.CheckboxInput: + type_ = "boolean" + + case forms.Select: + type_ = "string" + enum = [] # Fixme: load data from widget.options(…) + + case forms.NullBooleanSelect: + ... + + case forms.SelectMultiple: + ... + + case forms.RadioSelect: + ... + + case forms.CheckboxSelectMultiple: + ... + + case forms.SplitDateTimeWidget: + ... + + case forms.SplitHiddenDateTimeWidget: + ... + + case forms.SelectDateWidget: + ... + + self.schema["properties"][name] = { + "type": type_, + "title": str(field.label), + "description": str(field.help_text), + } + if x_display: + self.schema["properties"][name]["x-display"] = x_display + if format_: + self.schema["properties"][name]["format"] = format_ + if enum: + self.schema["properties"][name]["enum"] = enum -- GitLab