# HG changeset patch # User Sylvain Thénault # Date 1484904664 -3600 # Node ID af969080e7e64d749fd02ebb3da72226f4d3455f # Parent 8496135b6dc16dca0799e57c1eab5843a50b8509 [autoform] Go through guess_field even when field class is specified using uicfg guess_field does not only find the proper field class for some attribute/relation, but also do some basic configuration depending on e.g. constraints. Before this patch, if one was specifying explicitly the field class using uicfg.autoform_field, this automatic configuration wasn't happening. Change form.field_by_name and ff.guess_field so explicit class are also automatically configured now. Closes #14474840 diff -r 8496135b6dc1 -r af969080e7e6 cubicweb/web/formfields.py --- a/cubicweb/web/formfields.py Thu Jan 19 14:53:05 2017 +0100 +++ b/cubicweb/web/formfields.py Fri Jan 20 10:31:04 2017 +0100 @@ -1235,8 +1235,19 @@ kwargs.setdefault('label', (eschema.type, rschema.type)) kwargs.setdefault('help', rdef.description) if rschema.final: - fieldclass = FIELDS[targetschema] - if fieldclass is StringField: + fieldclass = kwargs.pop('fieldclass', FIELDS[targetschema]) + if issubclass(fieldclass, FileField): + if req: + aff_kwargs = req.vreg['uicfg'].select('autoform_field_kwargs', req) + else: + aff_kwargs = _AFF_KWARGS + for metadata in KNOWN_METAATTRIBUTES: + metaschema = eschema.has_metadata(rschema, metadata) + if metaschema is not None: + metakwargs = aff_kwargs.etype_get(eschema, metaschema, 'subject') + kwargs['%s_field' % metadata] = guess_field(eschema, metaschema, + req=req, **metakwargs) + elif issubclass(fieldclass, StringField): if eschema.has_metadata(rschema, 'format'): # use RichTextField instead of StringField if the attribute has # a "format" metadata. But getting information from constraints @@ -1253,18 +1264,6 @@ for cstr in rdef.constraints: if isinstance(cstr, SizeConstraint) and cstr.max is not None: kwargs['max_length'] = cstr.max - return StringField(**kwargs) - if fieldclass is FileField: - if req: - aff_kwargs = req.vreg['uicfg'].select('autoform_field_kwargs', req) - else: - aff_kwargs = _AFF_KWARGS - for metadata in KNOWN_METAATTRIBUTES: - metaschema = eschema.has_metadata(rschema, metadata) - if metaschema is not None: - metakwargs = aff_kwargs.etype_get(eschema, metaschema, 'subject') - kwargs['%s_field' % metadata] = guess_field(eschema, metaschema, - req=req, **metakwargs) return fieldclass(**kwargs) return RelationField.fromcardinality(card, **kwargs) diff -r 8496135b6dc1 -r af969080e7e6 cubicweb/web/test/unittest_views_forms.py --- a/cubicweb/web/test/unittest_views_forms.py Thu Jan 19 14:53:05 2017 +0100 +++ b/cubicweb/web/test/unittest_views_forms.py Fri Jan 20 10:31:04 2017 +0100 @@ -20,6 +20,8 @@ from cubicweb.devtools.testlib import CubicWebTC from cubicweb.web.views.autoform import InlinedFormField +from cubicweb.web.views.forms import EntityFieldsForm + class InlinedFormTC(CubicWebTC): @@ -68,6 +70,20 @@ InlinedFormField(view=formview)]) self.assertTrue(formview._get_removejs()) + def test_field_by_name_consider_aff(self): + class MyField(object): + def __init__(self, *args, **kwargs): + pass + + EntityFieldsForm.uicfg_aff.tag_attribute(('CWUser', 'firstname'), MyField) + try: + with self.admin_access.web_request() as req: + form = req.vreg['forms'].select('base', req, entity=req.user) + self.assertIsInstance(form.field_by_name('firstname', 'subject', req.user.e_schema), + MyField) + finally: + EntityFieldsForm.uicfg_aff.del_rtag('CWUser', 'firstname', '*', 'subject') + if __name__ == '__main__': import unittest diff -r 8496135b6dc1 -r af969080e7e6 cubicweb/web/views/forms.py --- a/cubicweb/web/views/forms.py Thu Jan 19 14:53:05 2017 +0100 +++ b/cubicweb/web/views/forms.py Fri Jan 20 10:31:04 2017 +0100 @@ -318,16 +318,16 @@ rschema = eschema.schema.rschema(name) # XXX use a sample target type. Document this. tschemas = rschema.targets(eschema, role) - fieldcls = cls_or_self.uicfg_aff.etype_get( + fieldclass = cls_or_self.uicfg_aff.etype_get( eschema, rschema, role, tschemas[0]) kwargs = cls_or_self.uicfg_affk.etype_get( eschema, rschema, role, tschemas[0]) if kwargs is None: kwargs = {} - if fieldcls: - if not isinstance(fieldcls, type): - return fieldcls # already and instance - return fieldcls(name=name, role=role, eidparam=True, **kwargs) + if fieldclass: + if not isinstance(fieldclass, type): + return fieldclass # already an instance + kwargs['fieldclass'] = fieldclass if isinstance(cls_or_self, type): req = None else: