Skip to content

Commit 5a07110

Browse files
tdruezavelis
authored andcommitted
Makes the Hook model available for extension (zapier#44)
* zapier#43: Make the Hook model available for extension as an Abstract model * Renamed Hook model to AbstractHook with the Meta abstract = True * The Hook model is the concrete implementation of the AbstractHook model * zapier#43: Add ability to provide a custom find_and_fire_hook() through a HOOK_FINDER setting * zapier#43: Add a 'Extend the Hook model' section in README
1 parent 56b7b82 commit 5a07110

File tree

3 files changed

+55
-5
lines changed

3 files changed

+55
-5
lines changed

README.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,3 +401,41 @@ def deliver_hook_wrapper(target, payload, instance, hook):
401401

402402
We also don't handle retries or cleanup. Generally, if you get a `410` or
403403
a bunch of `4xx` or `5xx`, you should delete the Hook and let the user know.
404+
405+
### Extend the Hook model:
406+
407+
The default `Hook` model fields can be extended using the `AbstractHook` model.
408+
For example, to add a `is_active` field on your hooks:
409+
410+
```python
411+
### models.py ###
412+
413+
from django.db import models
414+
from rest_hooks.models import AbstractHook
415+
416+
class CustomHook(AbstractHook):
417+
is_active = models.BooleanField(default=True)
418+
```
419+
420+
The extended `CustomHook` model can be combined with a the `HOOK_FINDER` setting
421+
for advanced QuerySet filtering.
422+
423+
```python
424+
### settings.py ###
425+
426+
HOOK_FINDER = 'path.to.find_and_fire_hook'
427+
428+
### utils.py ###
429+
430+
from .models import CustomHook
431+
432+
def find_and_fire_hook(event_name, instance, **kwargs):
433+
filters = {
434+
'event': event_name,
435+
'is_active': True,
436+
}
437+
438+
hooks = CustomHook.objects.filter(**filters)
439+
for hook in hooks:
440+
hook.deliver_hook(instance)
441+
```

rest_hooks/models.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,20 @@
3232
AUTH_USER_MODEL = getattr(settings, 'AUTH_USER_MODEL', 'auth.User')
3333

3434

35-
class Hook(models.Model):
35+
class AbstractHook(models.Model):
3636
"""
3737
Stores a representation of a Hook.
3838
"""
3939
created = models.DateTimeField(auto_now_add=True)
4040
updated = models.DateTimeField(auto_now=True)
4141

42-
user = models.ForeignKey(AUTH_USER_MODEL, related_name='hooks')
43-
event = models.CharField('Event', max_length=64,
44-
db_index=True)
42+
user = models.ForeignKey(AUTH_USER_MODEL, related_name='%(class)ss')
43+
event = models.CharField('Event', max_length=64, db_index=True)
4544
target = models.URLField('Target URL', max_length=255)
4645

46+
class Meta:
47+
abstract = True
48+
4749
def clean(self):
4850
""" Validation for events. """
4951
if self.event not in HOOK_EVENTS.keys():
@@ -107,6 +109,10 @@ def __unicode__(self):
107109
return u'{} => {}'.format(self.event, self.target)
108110

109111

112+
class Hook(AbstractHook):
113+
pass
114+
115+
110116
##############
111117
### EVENTS ###
112118
##############

rest_hooks/utils.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
from django.conf import settings
2+
3+
14
def get_module(path):
25
"""
36
A modified duplicate from Django's built in backend
@@ -86,4 +89,7 @@ def distill_model_event(instance, model, action, user_override=None):
8689
user_override = False
8790

8891
if event_name:
89-
find_and_fire_hook(event_name, instance, user_override=user_override)
92+
finder = find_and_fire_hook
93+
if getattr(settings, 'HOOK_FINDER', None):
94+
finder = get_module(settings.HOOK_FINDER)
95+
finder(event_name, instance, user_override=user_override)

0 commit comments

Comments
 (0)