Getting Started¶
Here you will understand how to use our WatcherMixins to decorate your Django Models and take advantage of the Hooks
Extend a base mixin, implementing the desired hook. check Create Your Watcher and Available Mixins.
Decorate you Model with watched decorator, check Decorate Your Model
The Hooks¶
Every basic data operation in Django can trigger a hook (Except read operations). And we have these hooks availables:
pre_create called by: CreateWatcherMixin, and SaveWatcherMixin
pre_update called by: UpdateWatcherMixin, and SaveWatcherMixin
pre_save called by: SaveWatcherMixin
pre_delete called by: DeleteWatcherMixin
post_create called by: CreateWatcherMixin, and SaveWatcherMixin
post_update called by: UpdateWatcherMixin, and SaveWatcherMixin
post_save called by: SaveWatcherMixin
post_delete called by: DeleteWatcherMixin
Each hook is a classmethod, it will always have the target param, update and create hooks will also have the meta_params param.
Target¶
MetaParams¶
The Metaparams is a TypedDict which will inform you about the trigger of the current operation:
source: str # "queryset" or "instance"
operation_params: dict # is the kwargs of the trigger operation
instance_ref: optional[models.Model] # in instance operations triggered by instances it will bring the reference to the instance that the operation was called
Create Your Watcher¶
The Watcher class is the core of our project, on that you will coordinate the hooks of your model.
We do give 3 basic mixins (DeleteWatcherMixin, CreateWatcherMixin, UpdateWatcherMixin) which will control your data flow.
Also, exists a 4th mixin that is a mix up of Create and Update mixins: SaveWatcherMixin.
These mixins will call the hooks in the approprieted order together with the desired operation everything inside a transaction, and it will Rollback if something goes wrong.
How to extend a basic mixins:
# my_app.watchers.py
from __future__ import annotation
from typing import TYPE_CHECKING, List
from django_watcher.mixins import CreateWatcherMixin, DeleteWatcherMixin
from .tasks import send_deletion_email
if TYPE_CHECKING:
from .models import MyModel
class MyModelWatcher(CreateWatcherMixin, DeleteWatcherMixin):
@classmethod
def post_delete(cls, undeleted_instances: List[MyModel]):
send_deletetion_email(undeleted_instances)
@classmethod
def pre_create(cls, target: List[MyModel], meta_params: dict):
# do transformation, call functions, whatever you feel necessary
Usage of type hints is optional:
# my_app.watchers.py
from django_watcher.mixins import CreateWatcherMixin, DeleteWatcherMixin
from .tasks import send_deletion_email
class MyModelWatcher(CreateWatcherMixin, DeleteWatcherMixin):
@classmethod
def post_delete(cls, undeleted_instances):
send_deletetion_email(undeleted_instances)
@classmethod
def pre_create(cls, target, meta_params):
# do transformation, call functions, whatever you feel necessary
This section is only to show how easy is to use, but you can dive deep on the next section Available Mixins to check what are the available parameters of the hooks.
Available Mixins¶
DeleteWatcherMixin¶
The DeleteWatcherMixin extends our AbstractWatcher has the following hooks:
@classmethod
def pre_delete(cls, target: models.QuerySet) -> None:
...
@classmethod
def post_delete(cls, undeleted_instances: List[D]) -> None:
...
CreateWatcherMixin¶
The CreateWatcherMixin extends our AbstractWatcher has the following hooks:
@classmethod
def pre_create(cls, target: List['CreatedModel'], meta_params: MetaParams) -> None:
...
@classmethod
def post_create(cls, target: models.QuerySet, meta_params: MetaParams) -> None:
...
To understand what is MetaParams, click on the link.
UpdateWatcherMixin¶
The UpdateWatcherMixin extends our AbstractWatcher and has the following hooks:
@classmethod
def pre_update(cls, target: models.QuerySet, meta_params: MetaParams) -> None:
...
@classmethod
def post_update(cls, target: models.QuerySet, meta_params: MetaParams) -> None:
...
To understand what is MetaParams, click on the link.
SaveWatcherMixin¶
The SaveWatcherMixin extends CreateWatcherMixin and UpdateWatcherMixin has the same hooks of it supers and:
@classmethod
def pre_save(cls, target: Union[List['CreatedModel'], models.QuerySet], meta_params: MetaParams) -> None:
pass
@classmethod
def post_save(cls, target: models.QuerySet, meta_params: MetaParams) -> None:
pass
pre_save and post_save hooks will always run.
Create hooks order:
pre_save
pre_create
create
post_create
post_save
Update hooks order:
pre_save
pre_update
update
post_update
post_save
To understand what is MetaParams, click on the link.
Decorate Your Model¶
Setting the Watcher on the model:
# You will always decorate your model
from django_watcher.decorators import watched
# Approach #1 - Import the watcher locally
from my_app.whatchers import MyWatcher
@watched(MyWatcher)
class MyModel(models.Model):
...
# Approach #2 - Give a custom path
@watched('my_app.services.watchers.MyWatcher')
class MyModel(models.Model):
...
# Approach #3 - Give de module name + watcher name if is inside a `watchers.py` of the same django app
@watched('my_app.MyWatcher')
class MyModel(models.Model):
...
Using others than default django managers¶
Also if you have other managers (aside from objects) you can declarate it, on the seccond param of the watched decorator, default value is [‘objects’]:
from django_watcher.decorators import watched
@watched('my_app.MyWatcher', ['objects', 'deleted_objects'])
class MyModel(models.Model):
...