Где прописывается конфигурация Celery в Django
Что проверяют
Настраивали ли вы Celery сами или только видели готовый проект. Интервьюер ждёт три места: модуль с приложением Celery, импорт в __init__.py и параметры в settings.py. Следом спрашивают, как запускается beat и как тестировать задачи.
Как отвечать
proj/proj/celery.py: создаёте приложение и подключаете настройки Django. Внутриos.environ.setdefault("DJANGO_SETTINGS_MODULE", "proj.settings"), затемapp = Celery("proj"),app.config_from_object("django.conf:settings", namespace="CELERY")иapp.autodiscover_tasks(), который найдётtasks.pyво всех приложениях изINSTALLED_APPS;proj/proj/__init__.py: строкаfrom .celery import app as celery_app. Без неё приложение не загрузится вместе с Django, и@shared_taskбудет отправлять задачи в приложение по умолчанию;settings.py: сами параметры.namespace="CELERY"значит, что настройкаbroker_urlищется какCELERY_BROKER_URL,task_always_eagerкакCELERY_TASK_ALWAYS_EAGER. Обычно задаютCELERY_BROKER_URL,CELERY_RESULT_BACKEND,CELERY_TIMEZONE,CELERY_BEAT_SCHEDULE, лимиты вродеCELERY_TASK_TIME_LIMIT. Адрес брокера берут из переменных окружения, а не пишут в код.
Хорошо дополнить экосистемой: django-celery-beat хранит расписание в базе и даёт менять его из админки через DatabaseScheduler, django-celery-results пишет результаты задач в базу Django. Воркер и планировщик запускаются отдельными процессами: celery -A proj worker -l INFO и celery -A proj beat -l INFO.
Сериализатор json стоит по умолчанию начиная с Celery 4, поэтому прописывать его явно необязательно.
Где спотыкаются
Забывают импорт в __init__.py. Симптом узнаваемый: задачи пытаются уйти в RabbitMQ на localhost с учёткой guest, хотя в настройках указан Redis.
Пишут параметры без префикса или старыми именами из Celery 3, например BROKER_URL. С namespace="CELERY" такие настройки просто игнорируются, и никакой ошибки не будет.
Вызывают .delay() внутри транзакции. Воркер берёт задачу раньше коммита и не находит только что созданную запись. Отправку оборачивают в transaction.on_commit, а в задачу передают идентификатор, а не объект модели.