| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- from wtforms import FieldList, FormField
- from .iterators import iter_schema, iter_form
- from .utils import *
- from pydantic import ValidationError
- class SchemaToForm:
- _schema = None
- _errors = None
- def __init__(self, schema_class, form, lut=None):
- self.schema_class = schema_class
- self.form = form
- self.lut = lut if lut else lambda x: x
- def __call__(self, data):
- try:
- self._schema = self.schema_class(**data)
- self._errors = None
- except ValidationError as e:
- self._errors = defaultdict(list)
- for error in e.errors():
- light_error = {k: error[k] for k in error if k != 'loc'}
- recursive_dict_operation(
- self._errors,
- lambda d, k: d.setdefault(k, defaultdict(list)),
- lambda d, k: d[k].append(light_error),
- *error['loc']
- )
- self._errors = default_to_regular(self._errors)
- self._schema = self.schema_class.construct(data, self.schema_class.__fields__)
- @property
- def schema(self):
- return self._schema
- @property
- def errors(self):
- return self._errors
- @classmethod
- def get_item(cls, dict, key):
- for k in key:
- if is_int(k):
- sub_dict = dict[k]
- else:
- sub_dict = dict[k]
- return cls.get_item(sub_dict, key[1:])
- return dict
- @classmethod
- def get_field(cls, form, key):
- for k in key:
- if is_int(k):
- sub_form = form.entries[k]
- else:
- sub_form = getattr(form, k)
- return cls.get_field(sub_form, key[1:])
- return form
- @classmethod
- def get_schema(cls, schema, key):
- for k in key:
- if is_int(k):
- sub = schema[k]
- else:
- sub = getattr(schema, k)
- return cls.get_schema(sub, key[1:])
- return schema
- def set_data(self):
- for src_key, value in iter_schema(self.schema):
- dest_key = self.lut(src_key)
- dest_field = self.get_field(self.form, dest_key)
- dest_field.data = value
- def set_baked(self):
- for k, field in iter_form(self.form, leafs_only=False):
- field = self.get_field(self.form, k)
- if isinstance(field, FormField):
- field._baked_instance = self.get_schema(self.schema, k)
- def set_errors(self):
- for path, error_list in nested_dict_iter(self.errors):
- field = self.get_field(self.form, path)
- if isinstance(field, FormField):
- setattr(field.form, '_errors', error_list)
- else:
- setattr(field, 'errors', error_list)
- for path, error_list in nested_dict_iter(self.errors):
- paths_with_list = [
- (path[:n], path[n], path[n+1:])
- for n, val in enumerate(path) if is_int(val)
- ]
- for field_list, _, _ in paths_with_list:
- form = rgetattr(self.form, tuple(field_list))
- form.errors = [entry.errors for entry in form.entries]
|