[form] add a new ignore_req_params attribute on field controlling value's retreival stable
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Tue, 23 Feb 2010 12:43:15 +0100
branchstable
changeset 4658 25de2eb0432b
parent 4656 027bbff3659f
child 4659 f8326ff98f37
[form] add a new ignore_req_params attribute on field controlling value's retreival for such field, such as eid/__type in entity forms, we don't want to consider values from req.form since we may get undesired value (as reported by #714766). This new attribute allow do specify that we don't want to consider req.form in such case. Also, it seems that retreival of form values after a validation error suffer from the same problem, so don't use form_previous_values for field with ignore_req_params set to True (XXX though I suppose that may not be correct in some cases).
web/formfields.py
web/formwidgets.py
web/views/forms.py
--- a/web/formfields.py	Tue Feb 23 08:41:06 2010 +0100
+++ b/web/formfields.py	Tue Feb 23 12:43:15 2010 +0100
@@ -91,7 +91,10 @@
        optional fieldset to which this field belongs to
     :order:
        key used by automatic forms to sort fields
-
+    :ignore_req_params:
+       when true, this field won't consider value potentialy specified using
+       request's form parameters (eg you won't be able to specify a value using for
+       instance url like http://mywebsite.com/form?field=value)
     """
     # default widget associated to this class of fields. May be overriden per
     # instance
@@ -113,6 +116,7 @@
     order = None
     value = _MARKER
     fallback_on_none_attribute = False
+    ignore_req_params = False
 
     def __init__(self, name=None, label=_MARKER, widget=None, **kwargs):
         for key, val in kwargs.items():
--- a/web/formwidgets.py	Tue Feb 23 08:41:06 2010 +0100
+++ b/web/formwidgets.py	Tue Feb 23 12:43:15 2010 +0100
@@ -97,15 +97,20 @@
         return self.values(form, field), attrs
 
     def values(self, form, field):
-        qname = field.input_name(form, self.suffix)
-        if qname in form.form_previous_values:
-            values = form.form_previous_values[qname]
-        elif qname in form._cw.form:
-            values = form._cw.form[qname]
-        elif field.name != qname and field.name in form._cw.form:
-            # compat: accept attr=value in req.form to specify value of attr-subject
-            values = form._cw.form[field.name]
-        else:
+        values = None
+        if not field.ignore_req_params:
+            qname = field.input_name(form, self.suffix)
+            # value from a previous post that has raised a validation error
+            if qname in form.form_previous_values:
+                values = form.form_previous_values[qname]
+            # value specified using form parameters
+            elif qname in form._cw.form:
+                values = form._cw.form[qname]
+            elif field.name != qname and field.name in form._cw.form:
+                # XXX compat: accept attr=value in req.form to specify value of
+                # attr-subject
+                values = form._cw.form[field.name]
+        if values is None:
             values = self.typed_value(form, field)
             if values != INTERNAL_FIELD_VALUE:
                 values = self.format_value(form, field, values)
--- a/web/views/forms.py	Tue Feb 23 08:41:06 2010 +0100
+++ b/web/views/forms.py	Tue Feb 23 12:43:15 2010 +0100
@@ -223,8 +223,9 @@
             self.edited_entity = rset.complete_entity(row or 0, col or 0)
         msg = kwargs.pop('submitmsg', None)
         super(EntityFieldsForm, self).__init__(_cw, rset, row, col, **kwargs)
-        self.add_hidden('__type', self.edited_entity.__regid__, eidparam=True)
-        self.add_hidden('eid', self.edited_entity.eid)
+        self.add_hidden('__type', self.edited_entity.__regid__, eidparam=True,
+                        ignore_req_params=True)
+        self.add_hidden('eid', self.edited_entity.eid, ignore_req_params=True)
         if kwargs.get('mainform', True): # mainform default to true in parent
             self.add_hidden(u'__maineid', self.edited_entity.eid)
             # If we need to directly attach the new object to another one