Parcourir la source

Add support for baked_instance in form & subfields

theenglishway (time) il y a 6 ans
Parent
commit
2755389742
3 fichiers modifiés avec 37 ajouts et 2 suppressions
  1. 5 1
      pydantic_form/form.py
  2. 6 1
      pydantic_form/translator.py
  3. 26 0
      tests/test_process.py

+ 5 - 1
pydantic_form/form.py

@@ -20,13 +20,16 @@ class PydanticFieldList(FieldList):
 class PydanticForm(Form):
     _errors = {}
     _schema = None
-    _baked_instance = None
 
     def __init__(self, *args, **kwargs):
         self._errors = {}
         self.translator = SchemaToForm(self._schema, self)
         super().__init__(*args, **kwargs)
 
+    @property
+    def _baked_instance(self):
+        return self.translator._schema
+
     def process(self, formdata=None, obj=None, data=None, **kwargs):
         super().process()
         formdata = self.meta.wrap_formdata(self, formdata)
@@ -39,6 +42,7 @@ class PydanticForm(Form):
             self.translator.set_errors()
             return False
 
+        self.translator.set_baked()
         return True
 
     def process_obj(self, obj):

+ 6 - 1
pydantic_form/translator.py

@@ -55,7 +55,7 @@ class SchemaToForm:
 
     def set_data(self):
         schema = self._schema
-        for src_key, src_value in iter_schema(schema):
+        for src_key, src_value in iter_schema(self.schema):
             try:
                 value = rgetattr(schema, src_key)
             except AttributeError:
@@ -68,6 +68,11 @@ class SchemaToForm:
             dest_field = rgetattr(self.form, dest_key)
             setattr(dest_field, 'data', value)
 
+    def set_baked(self):
+        for k, field in iter_form(self.form, leafs_only=False):
+            if isinstance(field, FormField):
+                field._baked_instance = rgetattr(self.schema, k)
+
     def set_errors(self):
         for k, error_list in nested_dict_iter(self.errors):
             field = rgetattr(self.form, k)

+ 26 - 0
tests/test_process.py

@@ -115,3 +115,29 @@ def test_errors_invalid(scenario, data, errors_factory):
     assert form.errors
     for k, error in errors_factory(scenario).items():
         assert recursive_get(form.errors, *k)[0]['type'] == error
+
+
+@pytest.mark.parametrize(
+    'data',
+    ['valid'],
+    indirect=True
+)
+@pytest.mark.parametrize(
+    'scenario',
+    SCENARIOS,
+    indirect=True
+)
+def test_baked_instance(scenario, data):
+    form = scenario.form(data=data)
+
+    form.validate()
+
+    assert hasattr(form, '_baked_instance')
+    assert form._baked_instance is not None
+    assert form._baked_instance.dict() == data
+
+    for key, sub_form in iter_form(form, leafs_only=False):
+        if isinstance(sub_form, FormField):
+            assert hasattr(sub_form, '_baked_instance')
+            assert sub_form._baked_instance is not None
+            assert sub_form._baked_instance.dict() == recursive_get(data, *key)