Changeset 6273 for main/waeup.sirp/trunk/src/waeup/sirp/utils/converters.py
- Timestamp:
- 4 Jun 2011, 02:29:21 (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
main/waeup.sirp/trunk/src/waeup/sirp/utils/converters.py
r6263 r6273 245 245 from zope.formlib import form 246 246 from zope.formlib.form import ( 247 _widgetKey, WidgetInputError, ValidationError, InputErrors, expandPrefix) 247 _widgetKey, WidgetInputError, ValidationError, InputErrors, expandPrefix, 248 setUpInputWidgets) 248 249 from zope.formlib.interfaces import IInputWidget 249 250 from zope.publisher.browser import TestRequest 251 from waeup.sirp.interfaces import IObjectConverter 250 252 251 253 def getWidgetsData(widgets, form_prefix, data): 254 """Get data and validation errors from `widgets` for `data`. 255 256 Updates the dict in `data` with values from the widgets in 257 `widgets`. 258 259 Returns a list of tuples ``(<WIDGET_NAME>, <ERROR>)`` where 260 ``<WIDGET_NAME>`` is a widget name (normally the same as the 261 associated field name) and ``<ERROR>`` is the exception that 262 happened for that widget/field. 263 264 This is merely a copy from the same-named function in 265 :mod:`zope.formlib.form`. The only difference is that we also 266 store the fieldname for which a validation error happened in the 267 returned error list (what the original does not do). 268 269 """ 252 270 errors = [] 253 271 form_prefix = expandPrefix(form_prefix) … … 271 289 return errors 272 290 273 274 class IObjectConverter(Interface):275 def __init__(iface):276 """Create an converter.277 278 `iface` denotes the interface to which we want to turn any279 passed object.280 281 """282 283 def applyRowData(data_dict, context, form_fields=None):284 """Apply data in `data_dict` to `context`.285 286 `data_dict` is a dict containing field names as keys and an287 object or string as `context`.288 289 If `context` is a string, this is understood as a factory name290 and we will try to create a proper object calling291 ``createObject()``.292 293 `form_fields` are by default (``None``) buildt from the given294 `iface` but can also be passed in to override the295 default. This might be handy if you want to omit or select296 certains fields from the interface.297 298 Returns a tuple ``(<ERROR_LIST, INV_ERR_LIST, OBJ>)`` where299 ``ERROR_DICT`` is a dict of errors for single fields (if300 happened), ``INV_ERR_LIST`` is a list of invariant errors301 happened (errors that apply to several fields), and ``OBJ`` is302 the created/updated object.303 """304 305 291 class DefaultObjectConverter(grok.Adapter): 306 """An object converter can apply CSV data to objects. 307 308 Thus, in a way, it can turn CSV data into real objects. 292 """Turn string values into real values. 293 294 A converter can convert string values for objects that implement a 295 certain interface into real values based on the given interface. 309 296 """ 310 297 … … 314 301 def __init__(self, iface): 315 302 self.iface = iface 316 self. form_fields = form.Fields(iface)303 self.default_form_fields = form.Fields(iface) 317 304 return 318 305 319 def applyRowData(self, data_dict, context, form_fields=None): 306 def fromStringDict(self, data_dict, context, form_fields=None): 307 """Convert values in `data_dict`. 308 309 Converts data in `data_dict` into real values based on 310 `context` and `form_fields`. 311 312 `data_dict` is a mapping (dict) from field names to values 313 represented as strings. 314 315 The fields (keys) to convert can be given in optional 316 `form_fields`. If given, form_fields should be an instance of 317 :class:`zope.formlib.form.Fields`. Suitable instances are for 318 example created by :class:`grok.AutoFields`. 319 320 If no `form_fields` are given, a default is computed from the 321 associated interface. 322 323 The `context` can be an existing object (implementing the 324 associated interface) or a factory name. If it is a string, we 325 try to create an object using 326 :func:`zope.component.createObject`. 327 328 Returns a tuple ``(<FIELD_ERRORS>, <INVARIANT_ERRORS>, 329 <DATA_DICT>)`` where 330 331 ``<FIELD_ERRORS>`` 332 is a list of tuples ``(<FIELD_NAME>, <ERROR>)`` for each 333 error that happened when validating the input data in 334 `data_dict` 335 336 ``<INVARIANT_ERRORS>`` 337 is a list of invariant errors concerning several fields 338 339 ``<DATA_DICT>`` 340 is a dict with the values from input dict converted. 341 342 If errors happen, i.e. the error lists are not empty, always 343 an empty ``<DATA_DICT>`` is returned. 344 345 If ``<DATA_DICT>` is non-empty, there were no errors. 346 """ 320 347 if form_fields is None: 321 form_fields = self.form_fields 348 form_fields = self.default_form_fields 349 350 request = TestRequest(form={}) 351 for key, val in data_dict.items(): 352 request.form['form.%s' % key] = val 322 353 323 354 obj = context 324 355 if isinstance(context, basestring): 325 356 obj = createObject(context) 326 request = TestRequest(form={}) 327 for key, val in data_dict.items(): 328 request.form['form.%s' % key] = val 329 widgets = form.setUpWidgets( 357 358 widgets = form.setUpInputWidgets( 330 359 form_fields, 'form', obj, request) 331 errors = getWidgetsData(widgets, 'form', data_dict) 332 err_messages = [] 333 if errors: 334 for key, error in errors: 335 message = error.args[0] 336 err_messages.append((key, message)) 337 invariant_errors = form.checkInvariants(form_fields, data_dict) 338 invariant_errors = [err.message for err in invariant_errors] 339 if not errors and not invariant_errors: 340 changed = form.applyChanges( 341 obj, form_fields, data_dict) 342 return err_messages, invariant_errors, obj 360 361 new_data = dict() 362 errors = getWidgetsData(widgets, 'form', new_data) 363 364 invariant_errors = form.checkInvariants(form_fields, new_data) 365 if errors or invariant_errors: 366 err_messages = [(key, err.args[0]) for key, err in errors] 367 invariant_errors = [err.message for err in invariant_errors] 368 return err_messages, invariant_errors, {} 369 370 return errors, invariant_errors, new_data
Note: See TracChangeset for help on using the changeset viewer.