Передавайте в Celery идентификатор Feedback, а не экземпляр ORM. Ставьте задачу после commit и изменяйте статус условно, чтобы не откатить более позднее состояние.
Обновление статуса Feedback через Celery после создания записи
Передавайте в Celery идентификатор Feedback, а не экземпляр ORM. Ставьте задачу после commit и изменяйте статус условно, чтобы не откатить более позднее состояние.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
После создания объекта Feedback инициируется Celery‑задача change_status_feedback, которая должна изменить его статус на in_progress. Требуется выполнить ревью кода: убедиться в корректном вызове задачи, правильной сериализации аргументов, корректной работе с ORM‑моделью и обработке возможных исключений.
from asset_main.celery import app
@app.task(name='change_status_feedback')
def change_status_feedback(feedback):
feedback.status = 'in_progress'
feedback.save()
feedback = Feedback.objects.create(**validate_data)
change_status_feedback.delay(feedback)
Ответ
Передавайте в Celery идентификатор Feedback, а не экземпляр ORM. Ставьте задачу после commit и изменяйте статус условно, чтобы не откатить более позднее состояние.
from django.db import transaction
@app.task(name='change_status_feedback')
def change_status_feedback(feedback_id):
return Feedback.objects.filter(
pk=feedback_id, status='new'
).update(status='in_progress')
with transaction.atomic():
feedback = Feedback.objects.create(**validate_data)
transaction.on_commit(
lambda pk=feedback.pk: change_status_feedback.delay(pk)
)
new здесь обозначает начальный статус — его нужно сверить с моделью. Идентификатор сериализуется стандартным JSON, а задача читает актуальную запись. Повторный запуск безопасен благодаря условному обновлению. Отсутствующая или уже обработанная запись даст ноль обновлений. on_commit предотвращает чтение незафиксированной записи, но не гарантирует доставку при сбое брокера; для такой гарантии нужен outbox.