해당 글은 Celery 4.4.1 documentation을 읽으면서 혼자 정리한 글입니다.
원문은 [First steps with Django — Celery 4.4.1 documentation](https://docs.celeryproject.org/en/stable/django/first-steps-with-django.html)
여기에 있어요!
django에서 샐러리 활용하기
먼저 celery를 django prodjct에서 쓸려면 Celery library를 정의해줘야 한다.
일반적으로 모델링을 아래와 같이 했다고 가정한다.
- proj/
- manage.py
- proj/
- __init__.py
- settings.py
- urls.py
이럴 경우 proj/proj/celery.py 라는 파일을 새로 만들고 여기에 celery instance를 정의해주는 것을 추천한다.
proj/proj/celery.py
from __future__ import absolute_import, unicode_literals
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 doesn'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))
해당 파일에 이렇게 작성을 해주고 하나씩 알아보자. 아 이것을 알아보기 전에 먼저 proj/proj/__init__.py module을 작성해줘야 한다. init.py를 작성해주면 이것은 django가 시작했을 때, app을 load해주고, @shared_task decorator를 사용가능하게 되는 것을 보장한다.
proj/proj/init.py
from __future__ import absolute_import, unicode_literals
# 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',)
이제 celery.py에 있는 것을 하나씩 보자
from __future__ import absolute_import
이것은 celery.py module이 import 될 때 다른 library와 충돌되지 않도록 해준다.
그 이후에 DJANGO_SETTINGS_MODULE의 환경 변수를 설정해준다.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'proj.settings')
이 줄이 꼭 필요한 것은 아닌데, 이것을 해주면 항상 설정 모듈이 셀러리 프로그램으로 전달하지 않아도 된다.
app = Celery('proj')
이것은 우리의 libary instance를 이야기 해주는데, 많은 인스턴스를 가질 수 있지만 django를 사용할 때는 이유가 없다.
=> 이해가 안되네??
이제 django setting module을 샐러리 구성에 더해줘야하는데, 이것이 의미하는 것은 너는 복수의 구성 파일을 가질 필요가 없고, 대신에 django setting에서 celery 구성을 바로 할 수 있다. 하지만 너가 원하면 분리할 수도 있다.
app.config_from_object('django.conf:settings', namespace='CELERY')
위에 namespace를 설정해준 것은 celery 구성 옵션들이 모두 앞에 CELERY_가 붙게 되는 것을 의미한다. 예를 들면 broker_url 을 setting하면 이게 CELERY_BROKER_URL로 표시될 것이다. 이것은 worker setting에서도 적용되고, worker_concurrency가 CELERY_WORKER_CONCURRENCY로 표시 될 것이다.
그리고 일반적인 사항으로 재사용 가능한 앱은 모두 tasks.py에 빼서 정의하는 것이다. 그리고 celery에서는 이것은 자동적으로 찾아주는 모듈을 가지고 있다. => tasks.py에 celery tasks에서 반복적으로 재사용할 앱을 정의하라
app.autodiscover_tasks()
위의 줄을 추가해주면 celery가 자동적으로 tasks를 찾는데, 우리가 설치되어 있는 앱에서 찾는다.
- app1/
- tasks.py
- models.py
- app2/
- tasks.py
- models.py
위와 같은 형태라면 celery에서 import 해주지 않아도, 알아서 tasks를 celery가 찾는다.
Using thr @shared_task decorator
재사용 가능한 app은 단지 한 프로젝트에 국한 되지 않을 것이고, 그래서 앱 instance를 다이렉트로 import 해줄 수가 없다.
하지만 @shared_task 데코레이터는 앱 인스턴스에 국한되지 않고 tasks를 생성해준다.
예를 들어보면 아래와 같다.
from __future__ import absolute_import, unicode_literals
from celery import shared_task
from demoapp.models import Widget
@shared_task
def add(x, y):
return x + y
@shared_task
def mul(x, y):
return x * y
@shared_task
def xsum(numbers):
return sum(numbers)
@shared_task
def count_widgets():
return Widget.objects.count()
@shared_task
def rename_widget(widget_id, name):
w = Widget.objects.get(id=widget_id)
w.name = name
w.save()
# 추가
작업 모듈을 가지고 오는데 일관성이 있어야 한다.
예를 들어 INSTALLED_APPS에 project.app가 있는 경우 project.app에서 작업을 가져와야 한다. 그렇지 않으면 작업 이름이 달라지게 된다.
'Django' 카테고리의 다른 글
장고 모델 생성시간 지정해주기 (0) | 2020.04.01 |
---|---|
django celery extension(django-celery-results) (0) | 2020.03.17 |
Django migration 되돌리기, 재실행 방법 (3) | 2020.01.29 |
Django select_related, prefetch_related에 대해서 (0) | 2019.12.28 |
Django queryset filter와 exists() (0) | 2019.12.28 |