thorn.decorators

Webhook decorators.

class thorn.decorators.webhook_model(on_create=None, on_change=None, on_delete=None, reverse=None, sender_field=None, **kwargs)[source]

Decorates models to send webhooks based changes to that model.

Keyword Arguments:
 
  • on_create (~thorn.Event) – Event to dispatch whenever an instance of this model is created (post_save).

  • on_change (~thorn.Event) – Event to dispatch whenever an instance of this model is changed (post_save).

  • on_delete (~thorn.Event) – Event to dispatch whenever an instance of this model is deleted (post_delete).

  • on_$event (~thorn.Event) – Additional user defined events.,

  • sender_field (str) – Default field used as a sender for events, e.g. "account.user", will use instance.account.user.

    Individual events can override the sender field user.

  • reverse (Callable) – A thorn.reverse.model_reverser instance (or any callable taking an model instance as argument), that describes how to get the URL for an instance of this model.

    Individual events can override the reverser used.

Examples

Simple article model, where the URL reference is retrieved by reverse('article-detail', kwargs={'uuid': article.uuid}):

@webhook_model(
    on_create=ModelEvent('article.created'),
    on_change=ModelEvent('article.changed'),
    on_delete=ModelEvent('article.removed'),
    on_deactivate=ModelEvent(
        'article.deactivate', deactivated__eq=True,
    )
    reverse=model_reverser('article-detail', uuid='uuid'),
)
class Article(models.Model):
    uuid = models.UUIDField()

The URL may not actually exist after deletion, so maybe we want to point the reference to something else in that special case, like a category that can be reversed by doing reverse('category-detail', args=[article.category.name]).

We can do that by having the on_delete event override the reverser used for that event only:

@webhook_model(
    on_create=ModelEvent('article.created'),
    on_change=ModelEvent('article.changed'),
    on_delete=ModelEvent(
        'article.removed',
        reverse=model_reverser('category-detail', 'category.name'),
    ),

    on_hipri_delete=ModelEvent(
        'article.internal_delete', priority__gte=30.0,
    ).dispatches_on_delete(),

    reverse=model_reverser('article-detail', uuid='uuid'),
)
class Article(model.Model):
    uuid = models.UUIDField()
    category = models.ForeignKey('category')
connect_events(events, **kwargs)[source]
contribute_to_event(event)[source]
data
update_events(events, **kwargs)[source]