Django -celery worker не получает задания
Я пытаюсь отправлять электронные письма через 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'])
он работает без функции .delay т.е. без celery. также терминал celery не получает никаких заданий.
t_user
имеет тип User
. Когда celery инициирует задачу через брокер, он должен сериализовать все параметры, необходимые задаче, чтобы задача (которая может находиться на другом сервере) могла десериализовать свои аргументы из брокера и работать с ними в безэталонном режиме.
Ошибка, которую вы видите, связана с тем, что celery не знает, как сериализовать экземпляр t_user
в json
. Вы можете сделать одно из двух: модифицировать производителя и потребителя, чтобы они работали с json-сериализованными словарями User
, или модифицировать настройки task_serializer
и accept_content
, чтобы включить pickle
.
Конечно, использование pickle
создает проблемы с безопасностью, если приложение-производитель, которому не доверяют, может инициировать выполнение задач, отправляя запросы на брокер. Если вас не беспокоит проблема ненадежных производителей, вы должны быть достаточно защищены (но вы можете захотеть прочитать обо всех уязвимостях, которым вы можете быть подвержены, используя pickle).
Подробнее о accept_content
и task_serializer
вы можете прочитать в документации по celery (ссылки предоставлены).