Commit ab388d7f authored by Julien Muchembled's avatar Julien Muchembled

ERP5Form: when editing a FormBox, do not compute the context twice (and wrongly)

This first reverts the following 2 commits:
  566c0c5f
  3a08c758

to at least fix the issue that the context method takes 2 arguments that aren't
available from FormBoxEditor.edit() without slowing things even more.

About deferred style, widget editor objects can be ignored for the moment. If
we ever need to restore fully functional objects, the regression in commit
  a5a2f1cd
could be solved with the following patch:

--- a/product/ERP5Form/FormBox.py
+++ b/product/ERP5Form/FormBox.py
@@ -131,22 +131,32 @@ def render(self, field, key, value, REQUEST, render_prefix=None):
 class FormBoxEditor:
   """An editor returned from FormBox validation able to `edit` document."""
 
+  path = None
+
   def __init__(self, result, context):
     """Initialize with all necessary information for editing.
 
     Keep a reference to the correct context and don't expect the caller to provide it
     during the edit phase because they don't have access to the widget anymore.
     """
     self.attr_dict, self.editor_list = result
+    self.context = context
     self.edit = lambda _: self._edit(context)
 
   def __getstate__(self):
-    pass
+    return (self.attr_dict, self.editor_list,
+            self.path or self.context.getPhysicalPath())
+
+  def __setstate__(self, state):
+    self.attr_dict, self.editor_list, self.path = state
 
   def __call__(self, REQUEST):
     # Called by Base_edit in case of FormValidationError
     pass
 
+  def edit(self, context):
+    return self._edit(context.unrestrictedTraverse(self.path))
+
   def _edit(self, context):
     """Edit inside correct context."""
     context.edit(**self.attr_dict)

This commit also removes the unused view() method on editors.

/reviewed-on nexedi/erp5!622
parent a0a543f8
......@@ -131,34 +131,33 @@ class FormBoxWidget(Widget.Widget):
class FormBoxEditor:
"""An editor returned from FormBox validation able to `edit` document."""
def __init__(self, result, context_method_id=None):
"""Initialize with all necessary information for editing a document.
def __init__(self, result, context):
"""Initialize with all necessary information for editing.
:result: tuple of attributes, editors intended as parameters for edit function
:context_method_id: editor needs to operate on the correct context (Document)
but it cannot hold reference because then weird failures
appear; thus we keep name of the context-obtaining method
Keep a reference to the correct context and don't expect the caller to provide it
during the edit phase because they don't have access to the widget anymore.
"""
self.attr_dict, self.editor_list = result
self.context_method_id = context_method_id
self.edit = lambda _: self._edit(context)
def view(self):
return self.__dict__
def __getstate__(self):
# With deferred style, to render reports of form in activities (and never
# to edit), we could be pickled but it's always for nothing for the moment.
pass
def __call__(self, REQUEST):
# Called by Base_edit in case of FormValidationError
pass
def edit(self, context):
if self.context_method_id:
context = getattr(context, self.context_method_id)()
def _edit(self, context):
"""Edit inside correct context."""
context.edit(**self.attr_dict)
for encapsulated_editor in self.editor_list:
encapsulated_editor.edit(context)
def as_dict(self):
"""
This method is used to return parameter dict.
This method is used by Base_callDialogMethod.
XXX This API is probably not stable and may change, as some editors are used to
edit multiple objects.
"""
......@@ -186,7 +185,6 @@ class FormBoxValidator(Validator.Validator):
def validate(self, field, key, REQUEST):
# TODO: Handle 'cell' for validation inside listboxes,
# like it is done for rendering.
context_method_id = field.get_value('context_method_id')
formbox_target_id = field.get_value('formbox_target_id')
# Get current error fields
......@@ -196,7 +194,7 @@ class FormBoxValidator(Validator.Validator):
# XXX Hardcode script name
result, result_type = here.Base_edit(formbox_target_id, silent_mode=1, key_prefix=key)
if result_type == 'edit':
return FormBoxEditor(result, context_method_id)
return FormBoxEditor(result, here)
elif result_type == 'form':
formbox_field_errors = REQUEST.get('field_errors', [])
current_field_errors.extend(formbox_field_errors)
......
......@@ -465,9 +465,6 @@ class MultiRelationEditor:
# Make sure no default value appears
REQUEST.set(self.field_id, None) # XXX Dirty
def view(self):
return self.__dict__
def edit(self, o):
if self.relation_editor_list is None:
return
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment