Передавать ORM-объект в Celery некорректно для обычного JSON-сериализатора. Также APIView не предоставляет get_serializer/create-контракт, а отправка письма не согласована с записью статуса.
Оптимизация Celery‑задачи изменения статуса
Передавать ORM-объект в Celery некорректно для обычного JSON-сериализатора. Также APIView не предоставляет get_serializer/create-контракт, а отправка письма не согласована с записью статуса.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Проверьте, правильно ли реализована логика Celery‑задачи change_status_feedback.
@app.task(name='change_status_feedback')
def change_status_feedback(fb):
fb.status = 'in_progress'
send_mail()
fb.save()
class CreateFeedbackAPIView(APIView):
def create(self, request):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
feedback = Feedback.objects.create(**serializer.validated_data)
change_status_feedback.delay(feedback)
return feedback
Ответ
Передавать ORM-объект в Celery некорректно для обычного JSON-сериализатора. Также APIView не предоставляет get_serializer/create-контракт, а отправка письма не согласована с записью статуса.
Используйте CreateAPIView с serializer_class и perform_create, либо определите post и сериализатор явно. Возвращайте DRF Response, а не модель напрямую. После сохранения ставьте задачу через transaction.on_commit, передавая feedback.pk.
В задаче получайте актуальную запись и проверяйте допустимость перехода статуса. Повторные исполнения Celery возможны: письмо без защиты будет отправлено повторно. Простая перестановка send_mail и save не решает проблему — сбой между ними оставит рассогласованность. Надёжный вариант фиксирует переход и outbox-событие одной транзакцией, а отдельная доставка использует идемпотентность и учёт результата.