Open obscode opened 8 years ago
+1 i've found the same error this week. And i hacked the form in the same way, but i'd like to fix it in a safe way.
Any ideas?
Same error here with the last version in Plone5.2/python3. Hardcoding auto_append to False is not working
That problem haunted me too today. What I found out:
collective.z3cform.datagridfield.datagridfield.DataGridField
is a instance of z3c.form.widget.MultiWidget
.extract
method in the MultiWidget expects a counter variable in request.form
which defines how much different rows are submitted.self.getWidget(idx)
returns a valid row. Otherwose it will return a <NO_VALUE>
object. The comparison against the NO_VALUE class then fails, as we have seen in the PicklingError, for whatever reason. Normally, no one should be able to import the NO_VALUE class from z3c.form.interfaces
. However, I guess this is a bug in z3c.form. With a pdb in the extract method, try to self.getWidget(0)
and if you submitted at least one row you should get a DataGridFieldObject
or the like back. Try to self.getWidget("TT").value
, that should be the template row. And a self.getWidget("abc").value
will return <NO_VALUE>
.count
.This should get fixed in this PR: https://github.com/collective/collective.z3cform.datagridfield/pull/106
Should be fixed with: https://github.com/collective/collective.z3cform.datagridfield/pull/106
It happened to me with DataGridField and LinkFieldWidget.
Using this awesome widget in a form. I want to disable the auto_append feature. I followed the instructions in the README file and used the form's updateWidgets() function to set the widget's auto_append = False.
If I fill out the data with a single row (i.e., DO NOT add or subtract), and I get an error: [...] PicklingError: Can't pickle <class 'z3c.form.interfaces.NO_VALUE'>: it's not the same object as z3c.form.interfaces.NO_VALUE
This occurs because when rendering the HTML for the widget, two rows are made: the input row and the template for the next added row (the 'TT' row). But the hidden count variable is set to 2 instead of 1 and this causes (I'm guessing) the NO_VALUE problem. Interestingly, if I add a row, then subtract it, the count goes down to 1 and the form submits correctly. I guess the JS logic fixes the problem in this case.
Debugging a bit, it seems that the function datagridfield.DataGridField.updateWidgets() will always add the "AA" and "TT" widgets because this is run before auto_append can be set to False (it is run as part of the super class' updateWidgets()). So there are always at least 3 widgets. But in the page template for the widget (datagridfield_input.pt) there is a conditional that will prevent the 'AA' widget from rendering if auto_append is False (which it is by the time the page template is rendered). So there's a timing with when self.auto_append is accessed giving inconsistent values.
I fixed the issue for this specific case by simply hacking datagridfield.py and hard-coding the default auto_append=False so everything is consistent from the get-go. But that's not a good solution. Not sure what is.