django-celeryを使わずにDjangoとCeleryを組み合わせて使う

DjangoCeleryを組み合わせて使う際に、django-celeryのモデルのテーブルを作りたくなかったり、各種機能が不要でシンプルに動かしたかった。
Celery - Distributed Task Queue — Celery 5.3.0b2 documentation
Celerydjango-celeryはドキュメントが少し足りなくて、設定方法がわかりにくかったのでメモを残しておく。
自分の都合の良いように設定してるので、よくわからない人はdjango-celeryを使ったほうがいいと思う。
試したバージョンは、Python3.4, Django1.8, Celery3.1。

Celeryのアプリケーションを返す関数の用意

まず、Celeryインスタンスを返す関数を用意する。これはCelery起動用に使うのと、Django側のセットアップに使う。
Djangoのプロジェクト名はmyproject。Celeryの設定は、 django.conf.settings を読むことにする。

myproject/celery_app.py
app = None


def get_celery_app():
    global app
    import celery
    if app is not None:
        return app
    app = celery.Celery('myproject')
    app.config_from_object('django.conf:settings')
    return app

Celeryを起動するためのモジュールと設定を用意する

celeryコマンドには、celery.appという名前でアクセス可能なモジュールを指定するので、プロジェクトディレクトリに用意する。
作成しておいたget_celery_app関数を呼ぶ前に、django.setupでDjangoのアプリケーションをロードしておくことに注意する(Djangoアプリの初期化処理などを動かしておくため)。
autodiscover_tasksメソッドで各Djangoアプリケーションのtasks.pyをロードする。

myproject/celery.py
import os

import django
from django.conf import settings

from .celery_app import get_celery_app

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
django.setup()

app = get_celery_app()
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
myproject/settings.py
# (省略)

# Celeryの設定を追記
CELERY_ALWAYS_EAGER = False  # 開発時はEAGERで動かすと便利
CELERY_EAGER_PROPAGATES_EXCEPTIONS = True
BROKER_URL = 'redis://'  # BrokerにはとりあえずRedisを使っとく

ここまでファイルを用意すると、以下のコマンドでCeleryのワーカーを起動できる。ブローカーを事前に起動しておくことに注意(この設定だとRedis)

$ celery -A myproject worker

Djangoの設定ファイルを別のものに切り替えたい場合は、DJANGO_SETTINGS_MODULE環境変数に指定することで変更できる。

Django側でCeleryに設定を反映するためのアプリケーションを用意する

AppConfigのreadyでget_celery_app関数を呼んで、Djangoのsettings.pyに記載したCeleryの設定を適用するためのクラスを用意する。

celery_config/apps.py
from django.apps import AppConfig


class CeleryConfig(AppConfig):
    name = 'celery_config'

    def ready(self):
        from myproject.celery_app import get_celery_app
        get_celery_app()
celery_config/__init__.py

用意したクラスは、__init__.pyでデフォルトに設定しておく。

default_app_config = 'celery_config.apps.CeleryConfig'
myproject/settings.py(抜粋)

celery_configを有効にする

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'celery_config',  # 追加した
    'myapp',
)

タスクを実装する

CeleryのタスクをDjangoアプリケーション内のtasks.pyに記述する。

myapp/tasks.py
from celery import shared_task

from .models import Message


@shared_task
def create_message(body):
    Message.objects.create(body=body)

Djangoアプリケーションからタスクを呼ぶ

タスクを呼ぶには、tasks.pyの関数をdelayメソッドで呼べばよい。

myapp/views.py
def create_message(request):
    tasks.create_message.delay(request.GET.get('body'))
    return render(request, 'create_message.html')

終わり。

コード

この設定例のプロジェクトのコードはgithubに置いた。
sample_nullpobug/django/django_celery at main · tokibito/sample_nullpobug · GitHub