#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
в документации по сельдерею (ссылки прилагаются).