What is the 'correct way' to validate DataGridfields ?
In 'normal field', I can validate with
def company_letter_kodeConstraint(value):
"""Check that the company_3 letter code is upperclass
"""
if not value.isupper():
#Does not work with datagridfield, gives error in browser
raise Invalid(_(u"Only capital letters for Company 3 letter code"))
#Works with datagridfield, but will show error message 'Constraint not satisfied /The system could not process the given value.'
return False
return True
UPDATE: This might be due to 'bootstrap stuff', because the following works (but will return the error message)
def company_letter_kodeConstraint(value):
"""Check that the company_3 letter code is upperclass
"""
if not value.isupper():
raise InvalidValue() #raise InvalidValue(_(u"This message will not show "))
return True
I'm running into the same issue I think, in Plone 5.2, DGF 1.5.3.
def filesize_limit(data, limit=5):
mbs = data.size/1024/1024
if mbs > limit:
raise Invalid(f'File must not exceed {limit} MB')
def validate_presentation(val):
filesize_limit(val, 5)
class IPresentation(model.Schema):
file = NamedBlobFile(
title='Attachment',
description='If available, upload an image of the presenter(s) at the event or a flyer '
'of the event (less than 5 MB).',
required=False,
constraint=validate_presentation
)
class IMySchema(model.Schema):
directives.widget(presentations=BlockDataGridFieldFactory)
presentations = schema.List(
title='Presentations',
value_type=DictRow(title="Presentation", schema=IPresentation),
required=False,
)
In the Dexterity add form, if I set the schema just to IPresentation (no DGF) it works as expected. With the schema set IMySchema, validation fails but instead of being caught and a warning shown it just displays the traceback.
I tried raising a ValidationError instead. This led to the message "The system could not process the given value." on the presentations field and "Raised if the Validation process fails." on the presentations sub field.
Here's one solution, though not ideal: remove constraints from the schema and validate instead on the form's handler.
def validate_presentation(val):
if not filesize_limit(val['file'], 5):
raise WidgetActionExecutionError('presentations',
Invalid(f'File size must not exceed 5 MB'))
...
@button.buttonAndHandler(_("Save"), name="save")
def handleAdd(self, action):
data, errors = self.extractData()
if errors:
self.status = self.formErrorsMessage
return
for presentation in data['presentations']:
validate_presentation(presentation)
Not ideal, as it highlights the entire DGF.
edit:
This doesn't work if I move the field "presentations" into a fieldset. Ideally I still want to assign validation directory to a schema field anyway.