# HG changeset patch # User Sylvain Thénault # Date 1375358111 -7200 # Node ID 312062f539810e06930ba596ce0a483ec5a5b298 # Parent 0d346a0a1451cd09a0734b7df00a47d9f65c791d [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'. diff -r 0d346a0a1451 -r 312062f53981 web/formfields.py --- 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 diff -r 0d346a0a1451 -r 312062f53981 web/test/data/schema.py --- 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 . -""" - -""" from yams.buildobjs import (EntityType, RelationDefinition, SubjectRelation, String, Int, Datetime, Boolean, Float) diff -r 0d346a0a1451 -r 312062f53981 web/test/unittest_views_basecontrollers.py --- 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):