Ver código fonte

Fix errors setting, and update schema iterator for 'construct'

theenglishway (time) 6 anos atrás
pai
commit
30a7d9daa4

+ 24 - 10
pydantic_form/iterators.py

@@ -8,7 +8,7 @@ def iter_field(field, leafs_only=True, path=(), parent=None):
     if issubclass(field.field_class, FormField):
         field_class = field.kwargs['form_class']
         if path and not leafs_only:
-            yield path, field_class
+            yield path, field_class, parent
 
         for subfield_name, subfield in field_class._unbound_fields:
             yield from iter_field(subfield, leafs_only, path + (subfield_name,), parent)
@@ -24,7 +24,7 @@ def iter_form_class(form_class, leafs_only=True, path=()):
     field = getattr(form_class, path[-1]) if path else form_class
 
     if path and not leafs_only:
-        yield path, field
+        yield path, field, None
 
     try:
         for subfield_name, subfield in field._unbound_fields:
@@ -36,7 +36,7 @@ def iter_form_class(form_class, leafs_only=True, path=()):
         yield from iter_form_class(field, leafs_only, path)
 
 def iter_form(form, leafs_only=True):
-    for key, field, iterate_on in iter_form_class(form.__class__):
+    for key, field, iterate_on in iter_form_class(form.__class__, leafs_only):
         if iterate_on:
             value = rgetattr(form, iterate_on)
             for n, entry in enumerate(value.entries):
@@ -66,13 +66,27 @@ def iter_schema_class(schema, leafs_only=True, path=()):
         yield from iter_schema_class_field(field, leafs_only, path + (key,))
 
 def iter_schema(schema, leafs_only=True):
+    def get_schema_value(schema, key):
+        try:
+            return rgetattr(schema, key)
+        except AttributeError:
+            return recursive_get(getattr(schema, key[0]), *key[1:])
+
     for key, field, iterate_on in iter_schema_class(schema.__class__, leafs_only):
         if iterate_on:
-            sub_values = rgetattr(schema, iterate_on)
-            if isinstance(sub_values, list):
-                for n, sub_value in enumerate(sub_values):
-                    yield key + (n,), sub_value
-            else:
-                raise NotImplementedError()
+            try:
+                sub_values = get_schema_value(schema, iterate_on)
+                if isinstance(sub_values, list):
+                    for n, sub_value in enumerate(sub_values):
+                        yield key + (n,), sub_value
+                else:
+                    raise NotImplementedError()
+            except AttributeError:
+                ...
+
             continue
-        yield key, rgetattr(schema, key)
+
+        try:
+            yield key, get_schema_value(schema, key)
+        except AttributeError:
+            ...

+ 6 - 14
pydantic_form/translator.py

@@ -40,22 +40,14 @@ class SchemaToForm:
         return self._errors
 
     def set_data(self):
-        schema = self._schema
-        for src_key, src_value in iter_schema(self.schema):
-            try:
-                value = rgetattr(schema, src_key)
-            except AttributeError:
-                try:
-                    value = recursive_get(getattr(schema, src_key[0]), *src_key[1:])
-                except AttributeError:
-                    continue
-
+        for src_key, value in iter_schema(self.schema):
             dest_key = self.lut(src_key)
-            dest_field = rgetattr(self.form, dest_key)
-            if isinstance(dest_field, FieldList):
-                for n, f in enumerate(dest_field.entries):
-                    setattr(f, 'data', value[n])
+            if is_int(dest_key[-1]):
+                *dest_field, idx = dest_key
+                dest_field = rgetattr(self.form, dest_key[:-1])
+                dest_field.entries[idx].data = value
             else:
+                dest_field = rgetattr(self.form, dest_key)
                 setattr(dest_field, 'data', value)
 
     def set_baked(self):

+ 8 - 7
pydantic_form/utils.py

@@ -84,17 +84,18 @@ def formdata_mangle(data):
     return ImmutableMultiDict(to_formdata_item(data))
 
 
+def is_int(value):
+    try:
+        int(value)
+        return True
+    except ValueError:
+        return False
+
+
 def formdata_demangle(formdata):
     def iter_by_reverse_key_length(iter):
         return sorted(iter, key=lambda k: len(k[0]), reverse=True)
 
-    def is_int(value):
-        try:
-            int(value)
-            return True
-        except ValueError:
-            return False
-
     if not formdata:
         return None
 

+ 3 - 0
tests/test_iterators.py

@@ -37,6 +37,9 @@ def test_iterator_schema(scenario):
     assert [k for k, _, _ in iter_schema_class(scenario.schema)] == keys.class_
     assert [k for k, _ in iter_schema(schema_instance)] == keys.instance
 
+    schema_construct = scenario.schema.construct(data, scenario.schema.__fields__)
+    assert [k for k, _ in iter_schema(schema_construct)] == keys.instance
+
 
 @pytest.mark.parametrize(
     'scenario',