PythonAnywhere部署Django应用:验证邮件延迟发送问题求助
Django部署在PythonAnywhere的验证邮件发送问题
问题说明
在PythonAnywhere上部署的Django应用中,仅用户注册验证邮件存在异常:新用户注册时,验证邮件需重新加载管理面板才会发送;但欢迎邮件、联系表单邮件均能正常发送,且本地测试时验证邮件可即时发送。当前使用django-email-verification插件,通过Gmail发送邮件。
相关代码(views.py)
class RegisterView(CreateView): form_class = RegisterForm template_name = 'common/register.html' success_url = reverse_lazy('login') def dispatch(self, request, *args, **kwargs): if request.user.is_authenticated: return redirect('index') return super().dispatch(request, *args, **kwargs) def form_valid(self, form): form.save(commit=False) user_email = form.cleaned_data['email'] user_username = form.cleaned_data['username'] user_password = form.cleaned_data['password1'] user = UserModel.objects.create_user(username=user_username, email=user_email, password=user_password) user.is_active = False send_email(user) return HttpResponseRedirect(reverse('email sent')) def form_invalid(self, form): return super().form_invalid(form)
解决思路及方案
1. 确保用户对象正确保存并提交事务
当前代码中,修改user.is_active = False后未执行user.save(),且可能因Django事务延迟提交,导致django-email-verification无法读取到最新用户状态。调整代码如下:
from django.db import transaction def form_valid(self, form): form.save(commit=False) user_email = form.cleaned_data['email'] user_username = form.cleaned_data['username'] user_password = form.cleaned_data['password1'] user = UserModel.objects.create_user(username=user_username, email=user_email, password=user_password) user.is_active = False user.save() # 保存修改后的用户状态 transaction.commit() # 手动提交事务,确保数据立即写入数据库 send_email(user) return HttpResponseRedirect(reverse('email sent'))
2. 检查插件触发逻辑
确认django-email-verification的send_email函数是否依赖用户的数据库状态。如果插件内部需要读取数据库中的用户记录,未提交的事务会导致插件无法获取到is_active=False的用户,从而延迟触发邮件。
3. 验证PythonAnywhere邮件配置
- 确保Gmail的SMTP配置正确:使用
smtp.gmail.com,端口587,开启TLS,且账号已设置App Password(若开启了两步验证)。 - 可在PythonAnywhere的"Email"面板查看邮件发送日志,确认是否有发送失败或延迟记录。
4. 改用后台任务发送邮件
若事务延迟问题无法解决,可将邮件发送逻辑放到后台任务中,避免在请求周期内等待事务提交:
# 示例:使用django-rq(需先安装配置) from django_rq import enqueue def form_valid(self, form): # ... 其他代码 ... user.save() enqueue(send_email, user) # 异步发送邮件 return HttpResponseRedirect(reverse('email sent'))
内容的提问来源于stack exchange,提问作者Simeon Todorov
相关产品推荐
相关产品推荐

