Invoking logic from model's .save() method
Hi! I have peewee model with custom save method:
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title.lower())
return super().save(*args, **kwargs)
And If I call await self.manager.create(...) the save method will not call.
It may little confuse.
Yes, there's no way to call save() asynchronously. I agree it's not obvious and should be highlighted in docs. Thank you for the feedback!
Not sure where I should put my save() auto validation/transformation code then... perhaps in a model's _transform_mutations() method, that is called by an overloaded insert() and update() ?
PS. @rudyryk thanks for making this awesome library! It was a pleasure to replace all threadpool executor calls in my codebase :)
@gwillem Thank you :)
I think it's up to application code design. I prefer to leave that code in Manager subclasses and have some domain specific methods, so we can have an extra abstraction layer above models. That may be good for separation into multiple services in future.
But in fact, async code is usually more verbose for now and many design decisions still need to be made for better code.
Here's an example:
class PostManager(peewee_async.Manager):
async def create_for_user(self, user, **attributes):
"""Save post by user."""
# ...
async def create_from_rss(self, **rss_data):
"""Save post imported from RSS."""
# ...
I use this, which has generic validation if a model has a validate method:
class ValidationManager(peewee_async.Manager):
@asyncio.coroutine
def update(self, obj, **kwargs):
if hasattr(obj, 'validate'):
obj.validate()
return super().update(obj, **kwargs)
@asyncio.coroutine
def create(self, model_, **data):
"""WdG: overloaded, because we can run validate()
"""
inst = model_(**data)
if hasattr(inst, 'validate'):
inst.validate()
query = model_.insert(**dict(inst._data))
pk = yield from self.execute(query)
if pk is None:
pk = inst._get_pk_value()
inst._set_pk_value(pk)
inst._prepare_instance()
return inst
However, now I had to copy the create method. Hmm, I'd better pin my dependencies :D
This is probably related to #96