i sat on this problem for 10 hours now and i have no idea anymore. if anyone could give me a hint, i would really appreciate that.
story: i created a schema for a custom widget, wich renders, the form works, all fine so far.
problem: i need to create a nested schema so i can access ``children`` in my custom widget to transmit more than only one filed. i had different variations of schemas so far, which all kinda work - e.g. render - but on validation my problem is i cannot access the POST data of the children in my parent-schema.
class curry(object):
"""
class to curry a methods together with fewer arguments.
"""
def __init__(self, fun, *args, **kwargs):
self.fun = fun
self.pending = args[:]
self.kwargs = kwargs.copy()
def __call__(self, *args, **kwargs):
if kwargs and self.kwargs:
kw = self.kwargs.copy()
kw.update(kwargs)
else:
kw = kwargs or self.kwargs
return self.fun(*(self.pending + args), **kw)
@colander.deferred
def create_LocationPickerWidget(node, kw):
"""
callable to create the widget with a deferred paramater, here
"request"
gets applied by ``colander.Schema.bind(request=self.request)``
"""
request = kw["request"]
return LocationPickerWidget(request)
class Location(colander.MappingSchema):
location_search = colander.SchemaNode(
colander.String(),
name = "location_string.location_search",
validator=colander.Length(min=1),
)
location_point = colander.SchemaNode(
colander.String(),
name = "location_string.location_point",
widget = deform.widget.HiddenWidget(),
validator=colander.Length(min=1),
)
class LocationPicker(colander.MappingSchema):
"""
schema only for a step in the form to choose a location
"""
location_string = Location(
widget=create_LocationPickerWidget,
)
@classmethod
def prepare_location(cls, fieldname, value):
"""
deform preparer to convert a form submitted location in a real
location.
appended below
"""
if log.isEnabledFor(logging.WARN):
_out = StringIO()
pprint(value, stream=_out)
log.warn("%s.%s @%s value: %s", __name__, cls.__name__, fieldname, _out.getvalue())
if value:
lat, lng = value.split(',')
position = WKTSpatialElement('POINT({0} {1})'.format(lat, lng))
return position
return value
# adding a preparer to the mapping node will not work
LocationPicker.location_string.preparer =\
curry(LocationPicker.prepare_location, "XX_location_string_XX")
# those work
Location.location_search.preparer =\
curry(LocationPicker.prepare_location, "location_search")
Location.location_point.preparer =\
curry(LocationPicker.prepare_location, "location_point")