我正在尝试设置一个简单的任务来使用 django-verify-email 包和 celery 发送电子邮件验证
这是我的代码
#task.py
from celery import shared_task
from verify_email.email_handler import send_verification_email
@shared_task
def send_user_email(request, form):
inactive_user = send_verification_email(request, form)
#sign_up.py
from django.shortcuts import render, redirect
from django.contrib import messages
from .tasks import send_user_email
def signup(request, form_class, template_name, success_message, redirect_url):
if request.user.is_authenticated:
return redirect(redirect_url)
form = form_class()
if request.method == 'POST':
form = form_class(request.POST)
if form.is_valid():
send_user_email(request, form=form)
messages.success(request, success_message)
return redirect(redirect_url)
else:
messages.error(
request, f'Error creating account. Please check the form.')
return render(request, template_name, {'form': form})
context = {'form': form}
return render(request, template_name, context)
我在任务控制台上出现此错误
[2024-01-03 19:08:34,231: ERROR/ForkPoolWorker-2] Task user.tasks.send_user_email[1f521272-e7e4-4ae0-8fd8-ef1e0ad551e5] raised unexpected: AttributeError("'dict' object has no attribute 'save'")
Traceback (most recent call last):
File "/home/foli/code/django/freeacademy/.freemindedAcademy/lib/python3.10/site-packages/celery/app/trace.py", line 477, in trace_task
R = retval = fun(*args, **kwargs)
File "/home/foli/code/django/freeacademy/.freemindedAcademy/lib/python3.10/site-packages/celery/app/trace.py", line 760, in __protected_call__
return self.run(*args, **kwargs)
File "/home/foli/code/django/freeacademy/user/tasks.py", line 7, in send_user_email
inactive_user = send_verification_email(request, form_data)
File "/home/foli/code/django/freeacademy/.freemindedAcademy/lib/python3.10/site-packages/verify_email/email_handler.py", line 94, in send_verification_email
return _VerifyEmail().send_verification_link(request, form)
File "/home/foli/code/django/freeacademy/.freemindedAcademy/lib/python3.10/site-packages/verify_email/email_handler.py", line 32, in send_verification_link
inactive_user = form.save(commit=False)
AttributeError: 'dict' object has no attribute 'save'
我在网络控制台上出现此错误
Traceback (most recent call last):
File "/home/foli/code/django/freeacademy/.freemindedAcademy/lib/python3.10/site-packages/kombu/serialization.py", line 41, in _reraise_errors
yield
File "/home/foli/code/django/freeacademy/.freemindedAcademy/lib/python3.10/site-packages/kombu/serialization.py", line 220, in dumps
payload = encoder(data)
File "/home/foli/code/django/freeacademy/.freemindedAcademy/lib/python3.10/site-packages/kombu/utils/json.py", line 57, in dumps
return _dumps(s, cls=cls, **dict(default_kwargs, **kwargs))
File "/usr/lib/python3.10/json/__init__.py", line 238, in dumps
**kw).encode(obj)
File "/usr/lib/python3.10/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/usr/lib/python3.10/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "/home/foli/code/django/freeacademy/.freemindedAcademy/lib/python3.10/site-packages/kombu/utils/json.py", line 45, in default
return super().default(o)
File "/usr/lib/python3.10/json/encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
During handling of the above exception (Object of type WSGIRequest is not JSON serializable), another exception occurred:
File "/home/foli/code/django/freeacademy/.freemindedAcademy/lib/python3.10/site-packages/django/core/handlers/exception.py", line 55, in inner
response = get_response(request)
File "/home/foli/code/django/freeacademy/.freemindedAcademy/lib/python3.10/site-packages/django/core/handlers/base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/foli/code/django/freeacademy/user/views.py", line 128, in teacher_signup
return signup(
File "/home/foli/code/django/freeacademy/user/user_signup.py", line 17, in signup
send_user_email.delay(request, form)
File "/home/foli/code/django/freeacademy/.freemindedAcademy/lib/python3.10/site-packages/celery/app/task.py", line 444, in delay
return self.apply_async(args, kwargs)
File "/home/foli/code/django/freeacademy/.freemindedAcademy/lib/python3.10/site-packages/celery/app/task.py", line 594, in apply_async
return app.send_task(
File "/home/foli/code/django/freeacademy/.freemindedAcademy/lib/python3.10/site-packages/celery/app/base.py", line 799, in send_task
amqp.send_task_message(P, name, message, **options)
File "/home/foli/code/django/freeacademy/.freemindedAcademy/lib/python3.10/site-packages/celery/app/amqp.py", line 518, in send_task_message
ret = producer.publish(
File "/home/foli/code/django/freeacademy/.freemindedAcademy/lib/python3.10/site-packages/kombu/messaging.py", line 175, in publish
body, content_type, content_encoding = self._prepare(
File "/home/foli/code/django/freeacademy/.freemindedAcademy/lib/python3.10/site-packages/kombu/messaging.py", line 268, in _prepare
body) = dumps(body, serializer=serializer)
File "/home/foli/code/django/freeacademy/.freemindedAcademy/lib/python3.10/site-packages/kombu/serialization.py", line 219, in dumps
with _reraise_errors(EncodeError):
File "/usr/lib/python3.10/contextlib.py", line 153, in __exit__
self.gen.throw(typ, value, traceback)
File "/home/foli/code/django/freeacademy/.freemindedAcademy/lib/python3.10/site-packages/kombu/serialization.py", line 45, in _reraise_errors
reraise(wrapper, wrapper(exc), sys.exc_info()[2])
File "/home/foli/code/django/freeacademy/.freemindedAcademy/lib/python3.10/site-packages/kombu/exceptions.py", line 34, in reraise
raise value.with_traceback(tb)
File "/home/foli/code/django/freeacademy/.freemindedAcademy/lib/python3.10/site-packages/kombu/serialization.py", line 41, in _reraise_errors
yield
File "/home/foli/code/django/freeacademy/.freemindedAcademy/lib/python3.10/site-packages/kombu/serialization.py", line 220, in dumps
payload = encoder(data)
File "/home/foli/code/django/freeacademy/.freemindedAcademy/lib/python3.10/site-packages/kombu/utils/json.py", line 57, in dumps
return _dumps(s, cls=cls, **dict(default_kwargs, **kwargs))
File "/usr/lib/python3.10/json/__init__.py", line 238, in dumps
**kw).encode(obj)
File "/usr/lib/python3.10/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/usr/lib/python3.10/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "/home/foli/code/django/freeacademy/.freemindedAcademy/lib/python3.10/site-packages/kombu/utils/json.py", line 45, in default
return super().default(o)
File "/usr/lib/python3.10/json/encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
Exception Type: EncodeError at /users/teacher_signup/
Exception Value: Object of type WSGIRequest is not JSON serializable
我认为问题来自包中的 inactive_user 变量。 我尝试了很多配置,但都不起作用
send_user_email
是一个 celery 任务,因此您传递给它的任何参数都需要是 可序列化(请参阅相关主题)。
对于使用 celery 来说,
django-verify-email
似乎不是一个好的选择,因为 django request
对象在内部被大量使用,这使得不可能以某种方式进行重构,使任务可序列化,而无需重写大部分逻辑。