move autoform's field_by_name implementation on base EntityFieldsForm
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Wed, 13 Jan 2010 17:44:11 +0100
changeset 4236 9260403bfe0b
parent 4235 49eb7e87d36d
child 4237 87d9431243ad
move autoform's field_by_name implementation on base EntityFieldsForm
web/views/autoform.py
web/views/editforms.py
web/views/forms.py
--- a/web/views/autoform.py	Wed Jan 13 17:42:27 2010 +0100
+++ b/web/views/autoform.py	Wed Jan 13 17:44:11 2010 +0100
@@ -9,12 +9,11 @@
 __docformat__ = "restructuredtext en"
 _ = unicode
 
-from logilab.common.decorators import iclassmethod, cached
+from logilab.common.decorators import cached
 
 from cubicweb import typed_eid
 from cubicweb.web import stdmsgs, uicfg
 from cubicweb.web import form, formwidgets as fwdgs
-from cubicweb.web.formfields import guess_field
 from cubicweb.web.views import forms, editforms
 
 _afs = uicfg.autoform_section
@@ -44,41 +43,6 @@
     # set this to a list of [(relation, role)] if you want to explictily tell
     # which relations should be edited
     display_fields = None
-    # class attributes below are actually stored in the uicfg module since we
-    # don't want them to be reloaded
-    rfields = uicfg.autoform_field
-    rfields_kwargs = uicfg.autoform_field_kwargs
-
-    # class methods mapping schema relations to fields in the form ############
-
-    @iclassmethod
-    def field_by_name(cls_or_self, name, role=None, eschema=None):
-        """return field with the given name and role. If field is not explicitly
-        defined for the form but `eclass` is specified, guess_field will be
-        called.
-        """
-        try:
-            return super(AutomaticEntityForm, cls_or_self).field_by_name(name, role)
-        except form.FieldNotFound:
-            if eschema is None or role is None or not name in eschema.schema:
-                raise
-            rschema = eschema.schema.rschema(name)
-            # XXX use a sample target type. Document this.
-            tschemas = rschema.targets(eschema, role)
-            fieldcls = cls_or_self.rfields.etype_get(eschema, rschema, role,
-                                                     tschemas[0])
-            kwargs = cls_or_self.rfields_kwargs.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)
-            field = guess_field(eschema, rschema, role, eidparam=True, **kwargs)
-            if field is None:
-                raise
-            return field
 
     # base automatic entity form methods #######################################
 
--- a/web/views/editforms.py	Wed Jan 13 17:42:27 2010 +0100
+++ b/web/views/editforms.py	Wed Jan 13 17:44:11 2010 +0100
@@ -142,13 +142,11 @@
         lzone = self._build_landing_zone(landing_zone)
         # compute value, checking perms, build form
         if rschema.final:
-            form = self._build_form(entity, rtype, role, 'edition', default, reload, lzone)
+            form = self._build_form(entity, rtype, role, 'base', default, reload, lzone)
             if not self.should_edit_attribute(entity, rschema, role, form):
                 self.w(entity.printable_value(rtype))
                 return
             value = entity.printable_value(rtype) or default
-            self.relation_form(lzone, value, form,
-                               self._build_renderer(entity, rtype, role))
         else:
             rvid = self._compute_best_vid(entity.e_schema, rschema, role)
             rset = entity.related(rtype, role)
@@ -160,12 +158,13 @@
                 if rset:
                     self.w(value)
                 return
+            # XXX do we really have to give lzone twice?
             form = self._build_form(entity, rtype, role, 'base', default, reload, lzone,
                                     dict(vid=rvid, lzone=lzone))
-            field = guess_field(entity.e_schema, entity.schema.rschema(rtype), role)
-            form.append_field(field)
-            self.relation_form(lzone, value, form,
-                               self._build_renderer(entity, rtype, role))
+        field = form.field_by_name(rtype, role, entity.e_schema)
+        form.append_field(field)
+        self.relation_form(lzone, value, form,
+                           self._build_renderer(entity, rtype, role))
 
     def should_edit_attribute(self, entity, rschema, role, form):
         rtype = str(rschema)
@@ -174,7 +173,7 @@
         if 'main_hidden' in afs or not entity.has_perm('update'):
             return False
         try:
-            form.field_by_name(rtype, role)
+            form.field_by_name(rtype, role, entity.e_schema)
         except FieldNotFound:
             return False
         return True
@@ -262,7 +261,7 @@
         return u''
     def append_field(self, *args):
         pass
-    def field_by_name(self, rtype, role):
+    def field_by_name(self, rtype, role, eschema=None):
         return None
 
 
--- a/web/views/forms.py	Wed Jan 13 17:42:27 2010 +0100
+++ b/web/views/forms.py	Wed Jan 13 17:44:11 2010 +0100
@@ -9,15 +9,16 @@
 
 from warnings import warn
 
+from logilab.common.decorators import iclassmethod
 from logilab.common.compat import any
 from logilab.common.deprecation import deprecated
 
 from cubicweb import typed_eid
 from cubicweb.selectors import non_final_entity, match_kwargs, one_line_rset
 from cubicweb.web import INTERNAL_FIELD_VALUE, eid_param
-from cubicweb.web import form, formwidgets as fwdgs
+from cubicweb.web import uicfg, form, formwidgets as fwdgs
 from cubicweb.web.controller import NAV_FORM_PARAMETERS
-from cubicweb.web.formfields import StringField, relvoc_unrelated
+from cubicweb.web.formfields import StringField, relvoc_unrelated, guess_field
 
 
 class FieldsForm(form.Form):
@@ -177,6 +178,8 @@
             renderer = self.form_default_renderer()
         return renderer.render(self, values)
 
+_AFF = uicfg.autoform_field
+_AFF_KWARGS = uicfg.autoform_field_kwargs
 
 class EntityFieldsForm(FieldsForm):
     __regid__ = 'base'
@@ -186,6 +189,33 @@
     internal_fields = FieldsForm.internal_fields + ('__type', 'eid', '__maineid')
     domid = 'entityForm'
 
+    @iclassmethod
+    def field_by_name(cls_or_self, name, role=None, eschema=None):
+        """return field with the given name and role. If field is not explicitly
+        defined for the form but `eclass` is specified, guess_field will be
+        called.
+        """
+        try:
+            return super(EntityFieldsForm, cls_or_self).field_by_name(name, role)
+        except form.FieldNotFound:
+            if eschema is None or role is None or not name in eschema.schema:
+                raise
+            rschema = eschema.schema.rschema(name)
+            # XXX use a sample target type. Document this.
+            tschemas = rschema.targets(eschema, role)
+            fieldcls = _AFF.etype_get(eschema, rschema, role, tschemas[0])
+            kwargs = _AFF_KWARGS.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)
+            field = guess_field(eschema, rschema, role, eidparam=True, **kwargs)
+            if field is None:
+                raise
+            return field
+
     def __init__(self, *args, **kwargs):
         self.edited_entity = kwargs.pop('entity', None)
         msg = kwargs.pop('submitmsg', None)