django -сельдерейный рабочий, не получающий задачи

#django #django-rest-framework #celery #django-celery

Вопрос:

Я пытаюсь отправлять электронные письма через Django celery, но сельдерей не получает заданий.

settings.py

 CELERY_BROKER_URL = 'redis://127.0.0.1:6379'
CELERY_RESULT_BACKEND = 'redis://127.0.0.1:6379'
CELERY_ACCEPT_CONTENT = ['application/json']
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TASK_SERIALIZER = 'json'
CELERY_TIMEZONE = "UTC"
 

tasks.py

 @app.task(name="send_activation_email")
def send_activation_email(user):
    
    to = user.email
    user_id = user.id
    subject = 'Activate Your %s Account' % user.get_user_role_display()
    text_content = ''
    uid = urlsafe_base64_encode(
        force_bytes(user_id))

    token = account_activation_token.make_token(user)
    c = ({'user': user,
          'user_type': user.user_role,
          'base_url': base_url, 'token': token, 'uid': uid, 'text_content': text_content})
    html_content = get_template('mail/user/invite.html').render(c)
    msg = EmailMultiAlternatives(
        subject, text_content, from_email, [to])
    msg.attach_alternative(html_content, "text/html")
    msg.send()
 

views.py

 class SignUpView(generics.ListAPIView):
    authentication_classes = ()
    permission_classes = ()
    renderer_classes = (JSONRenderer, )

    def post(self, request, user_role="employee",format=None, version=None):
        user = UsersSerializer(data=request.data,context={"user_role": user_role})
        if user.is_valid():
            t_user = user.save()
            send_activation_email.delay(t_user)
            message_data = custom_http_messages(
                code=200, message='You have successfully created your account.',data=user.data)
            return Response(message_data, status=message_data['code'])        
        else:
            message_data = custom_http_messages(
                    code=400, message='', data=user.errors)
            return Response(message_data, status=message_data['code'])
 

Получение ошибки
введите описание изображения здесь

он работает без .функция задержки, т.Е. без сельдерея. также терминал сельдерея не получает никаких задач.

Ответ №1:

t_user имеет тип User . Когда celery инициирует задачу через брокера, он должен сериализовать все параметры, необходимые задачам, чтобы задача (которая может находиться на другом сервере) могла десериализовать свои аргументы из брокера и работать с ними без состояния.

Ошибка , которую вы видите , заключается в том , что сельдерей не знает , как сериализовать t_user экземпляр json . Вы можете сделать одну из двух вещей: изменить как производителя, так и потребителя для работы с json-сериализованными User словарями или изменить параметры task_serializer и accept_content для включения pickle .

Конечно, использование pickle создает проблемы с безопасностью, если ненадежное приложение-производитель может инициировать задачи, отправляя запросы задач брокеру. Если вас не беспокоит проблема ненадежных производителей, вы должны быть в достаточной безопасности (но вы можете прочитать обо всех уязвимостях, которым вы можете быть подвержены при использовании pickle).

Вы можете прочитать больше о accept_content и task_serializer в документации по сельдерею (ссылки прилагаются).