[inlined form field] fix regression introduced in 3.16.4/570208f74a84. Closes #3064653
In the above changeset, we changed ordered entities to be edited according to
mandatory inlined constraints, though this leads to unpredictable order in
cases where there are no constraint. This leads to case where inlined relation
field may think there is no value related to a mandatory relation, while this
is simply because there is a value specified but to an entity that will be
created later (together with the relation).
To fix this, we've to use the fact that the RelationField.process_form_value
return None in cases where there is some entity to be created, while an empty
set when there are no linked entity. The new no_value() method allows to
differentiate between those different notion of 'no-value'.
--- a/web/formfields.py Thu Aug 01 10:59:52 2013 +0200
+++ b/web/formfields.py Thu Aug 01 13:55:11 2013 +0200
@@ -506,7 +506,7 @@
if field is self:
try:
value = field.process_form_value(form)
- if value is None and field.required:
+ if field.no_value(value) and field.required:
raise ProcessFormError(form._cw._("required field"))
yield field, value
except UnmodifiedField:
@@ -517,6 +517,11 @@
for field, value in field.process_posted(form):
yield field, value
+ @staticmethod
+ def no_value(value):
+ """return True if the value can be considered as no value for the field"""
+ return value is None
+
class StringField(Field):
"""Use this field to edit unicode string (`String` yams type). This field
@@ -1165,6 +1170,12 @@
eids.add(typed_eid)
return eids
+ @staticmethod
+ def no_value(value):
+ """return True if the value can be considered as no value for the field"""
+ # value is None is the 'not yet ready value, consider the empty set
+ return value is not None and not value
+
_AFF_KWARGS = uicfg.autoform_field_kwargs
--- a/web/test/data/schema.py Thu Aug 01 10:59:52 2013 +0200
+++ b/web/test/data/schema.py Thu Aug 01 13:55:11 2013 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -15,9 +15,6 @@
#
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""
-
-"""
from yams.buildobjs import (EntityType, RelationDefinition, SubjectRelation,
String, Int, Datetime, Boolean, Float)
--- a/web/test/unittest_views_basecontrollers.py Thu Aug 01 10:59:52 2013 +0200
+++ b/web/test/unittest_views_basecontrollers.py Thu Aug 01 13:55:11 2013 +0200
@@ -645,6 +645,34 @@
finally:
p.__class__.skip_copy_for = old_skips
+ def test_regr_inlined_forms(self):
+ self.schema['described_by_test'].inlined = False
+ try:
+ req = self.request()
+ req.data['eidmap'] = {}
+ req.data['pending_others'] = set()
+ req.data['pending_inlined'] = {}
+ req.form = {'eid': ['X', 'Y'], '__maineid' : 'X',
+
+ '__type:X': 'Salesterm',
+ '_cw_entity_fields:X': 'described_by_test-subject',
+ 'described_by_test-subject:X': 'Y',
+
+ '__type:Y': 'File',
+ '_cw_entity_fields:Y': 'data-subject',
+ 'data-subject:Y': (u'coucou.txt', Binary('coucou')),
+ }
+ values_by_eid = dict((eid, req.extract_entity_params(eid, minparams=2))
+ for eid in req.edited_eids())
+ editctrl = self.vreg['controllers'].select('edit', req)
+ # don't call publish to enforce select order
+ editctrl.errors = []
+ editctrl._to_create = {}
+ editctrl.edit_entity(values_by_eid['X']) # #3064653 raise ValidationError
+ editctrl.edit_entity(values_by_eid['Y'])
+ finally:
+ self.schema['described_by_test'].inlined = False
+
class ReportBugControllerTC(CubicWebTC):