Open meatballs opened 3 years ago
I really need to push meredydd to ok the class annotations in skulpt!
API for when validation occurs...
How about on_validation and on_validation attributes which can be set to callable?
good question I don't know enough about the library so ignore any code that is totally ignorant
# from the docs
@model_type
class Book:
title = Attribute()
published_on = Attribute()
author = Relationship(cls="Author")
fluent_python = Book.search(title="Fluent Python")[0]
fluent_python.title = "Fluent Python (Clear, Concise, and Effective Programming)"
fluent_python.save()
Could be - almost straight form the pydantic code
@model_type
class Book:
title = Attribute()
published_on = Attribute()
author = Relationship(cls="Author")
@validate('title')
def author_must_contain_space(v):
if ' ' not in v:
raise ValueError('must contain a space')
return v.title()
And the model could have some sort of validate method
fluent_python = Book.search(title="Fluent Python")[0]
fluent_python.title = "Fluent Python (Clear, Concise, and Effective Programming)"
try:
fluent_python.validate() # loops over all the validators
fluent_python.validate(key='title') # loops over all validators registered for title
except anvil_orm.ValidationError as e:
print(e)
else:
fluent_python.save()
The @validate would just append a method to a default_dict(list)
whose key is the attribute
calling .validate()
would catch ValueErrors
, AssertionErrors
and TypeErrors
and eventually raise a ValidationError after all validators were checked in a similar way to pydantic.
It could also potentially be some sort of context manager
with anvil_orm.validate(fluent_python) as v:
if v is not None:
pass
else:
print(v.errors) # there are errors
print(v.errors['title'])
just jamming so ignore what doesn't make sense.
My only reservation about raising errors is what then has to happen on a bound component using write back. Catching those errors becomes tricky.
Instead, I was wondering about either triggering an event or publishing a message. I opted for a generic callback so that the user can do whatever they like.
I like the decorators, though!
For a writeback in my head it would be something like
def on_validate(self, **event_args):
try:
self.item.validate()
except ValidationError as e:
self.author_error.text = e.errors['author']
And then you just have event_bindings for methods like lost_focus
set to on_validate
.
But again just throwing pasta
Having some time to have a crack at this properly would be nice!
Similar to how this is done by attrs and/or pydantic.