### Project Structure
```bash
proj
├──proj
| ├──__init__.py
| ├──settings.py
| └──celery.py
├──app1
| └──tasks.py
└──app2
└──tasks.py
```
### celery.py
Create the following file at the proj/proj/celery.py:
```python
import os
from celery import Celery
# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'proj.settings')
app = Celery('proj')
# Using a string here means the worker don't have to serialize
# the configuration object to child processes.
# - namespace='CELERY' means all celery-related configuration keys
# should have a `CELERY_` prefix.
app.config_from_object('django.conf:settings', namespace='CELERY')
# Load task modules from all registered Django app configs.
app.autodiscover_tasks()
@app.task(bind=True)
def debug_task(self):
print('Request: {0!r}'.format(self.request))
```
### settings.py
focus towards proj/proj/settings.py and add the following lines
```python
CELERY_BROKER_URL = "redis://redis:6379/0"
CELERY_RESULT_BACKEND = "redis://localhost:6379"
CELERY_ACCEPT_CONTENT = ["json"]
CELERY_TASK_SERIALIZER = "json"
CELERY_RESULT_SERIALIZER = "json"
```
### __init__.py
Don’t forget to add these lines at proj/proj/__init__.py:
```python
# This will make sure the app is always imported when
# Django starts so that shared_task will use this app.
from .celery import app as celery_app
__all__ = ['celery_app']
```
### Creating Task
at proj/app1/tasks.py
```python
from celery import task
@task()
def task_number_one():
# Do something...
```
And at proj/app2/tasks.py
```python
from celery import task
@task()
def task_number_two():
# Do another thing...
```
### Celery Beat Schedule
Back to proj/proj/settings.py, edit theCELERY_BEAT_SCHEDULE
```python
from celery.schedules import crontab
# Other Celery settings
CELERY_BEAT_SCHEDULE = {
'task-number-one': {
'task': 'app1.tasks.task_number_one',
'schedule': crontab(minute=59, hour=23)
},
'task-number-two': {
'task': 'app2.tasks.task_number_two',
'schedule': crontab(minute=0, hour='*/3,10-19')
}
}
```
or
```python
CELERY_BEAT_SCHEDULE = {
"get_random_joke": {
"task": "jokes.tasks.get_random_joke",
"schedule": 15.0
}
}
```
### Starting the Worker and the Beat
Celery requires both of the worker and the beat in order for tasks to execute as planned
```bash
$ celery -A proj worker -l info -B
```
#### Individual Service (for production)
```bash
$ celery -A proj worker -l info
$ celery -A proj beat -l info
```