Prepare
- Django project with long-task logic
- Celery with any backend
For example: send push after any event or auth user through sms code or email link.
Mark: to sign-in/sign-up users via SMS you may use this library
Problems
- Django signals synchronous by default
- We must to wait when transaction completed
- Clients can to wait response for a long time
Short description
- Configure celery
- Create application (for example,
notifier
) - Configure
post_save
signal throughcelery
task - Configure
AppConfig
to load function
Detail
- Create
notifier
application - Add
tasks.py
tasks.py
import uuid
from collections import namedtuple
from django.db.models.signals import post_save
from run_celery import app
from some_apps.models import SomeModel1, SomeModel2, SomeModel3
Ctx = namedtuple('Ctx', 'class_name identifier')
models = [
SomeModel1,
SomeModel2,
SomeModel3
]
def register_models():
for model in models:
post_save.connect(_post_save,
sender=model,
dispatch_uid=uuid.uuid4())
def _post_save(sender, instance, **kwargs):
ctx = Ctx(class_name=instance.__class__.__name__,
identifier=instance.pk)
_async_post_save_handler.delay(ctx)
@app.task
def _async_post_save_handler(ctx: Ctx):
"""
Get model and instance from notifier object and then make
some other logic
"""
...
Finally, add to apps.py
:
from django.apps import AppConfig
class NotifierConfig(AppConfig):
name = 'notifier'
def ready(self):
from apps.notifier.tasks import register_models
register_models() # here!
Save and run Django and run celery.
Conclusion
-
celery
help you create async handlers to your Django models - Solution is great to separate
post_save
and async logic
Thanks for reading
Top comments (2)
thanks a lot for this wonderful tips.... can I see what run_celery looks like??
AppRegistryNotReady("Apps aren't loaded yet.")