Django 的神秘问题 + uWSGI +发送电子邮件
经过大约 1.5 小时的艰苦调试后,我在这里给您写信。
首先,这些是感兴趣的文件:
/project/app/utils.py
from django.core.mail import EmailMultiAlternatives
import threading
class EmailThread(threading.Thread):
def __init__(self, subject, body, from_email, recipient_list, fail_silently, html):
self.subject = subject
self.body = body
self.recipient_list = recipient_list
self.from_email = from_email
self.fail_silently = fail_silently
self.html = html
threading.Thread.__init__(self)
def run(self):
msg = EmailMultiAlternatives(self.subject, self.body, self.from_email, self.recipient_list)
if self.html:
msg.attach_alternative(self.html, "text/html")
print "sending message"
msg.send(self.fail_silently)
print "sent."
def send_html_mail(subject, body, from_email, recipient_list, fail_silently=False, html=None, *args, **kwargs):
EmailThread(subject, body, from_email, [recipient_list], fail_silently, html).start()
/project/app/views.py
[...]
import utils
def my_view(request):
[...]
utils.send_html_mail('subject', '<h1>cool things.</h1>', 'Test <[email protected]>', '[email protected]', html='<h1>cool things.</h1>')
/project/app/settings。 py
# I use Amazon SES
[...]
EMAIL_BACKEND = 'backends.smtp.SSLEmailBackend'
EMAIL_HOST = 'amazon-server'
EMAIL_PORT = 465
EMAIL_HOST_USER = 'user'
EMAIL_HOST_PASSWORD = 'pass'
EMAIL_USE_TLS = True
[...]
/project/backends/smtp.py
# taken from https://gist.github.com/1486891
import smtplib
from django.core.mail.utils import DNS_NAME
from django.core.mail.backends.smtp import EmailBackend
class SSLEmailBackend(EmailBackend):
def open(self):
if self.connection:
return False
try:
self.connection = smtplib.SMTP_SSL(self.host, self.port,
local_hostname=DNS_NAME.get_fqdn())
if self.username and self.password:
self.connection.login(self.username, self.password)
return True
except:
if not self.fail_silently:
raise
好的,现在的问题是:
在 localhost 中:
- 从视图发送电子邮件works
- 从 django shell 发送电子邮件工作
在我的服务器上部署应用程序:
- 从视图发送电子邮件不起作用
- 从django shell发送电子邮件有效
localhost中的Django shell输出>:
# utils.send_html_mail('subject', '<h1>cool things.</h1>', 'Test <[email protected]>', '[email protected]', html='<h1>cool things.</h1>')
sending email
sent.
部署应用中的 Django shell 输出:
# utils.send_html_mail('subject', '<h1>cool things.</h1>', 'Test <[email protected]>', '[email protected]', html='<h1>cool things.</h1>')
sending email
相同的代码,相同的提交。问题可能出在 print "sent."
之前的方法 msg.send(self.fail_silently)
中,但它是什么?我没有想法。
你呢?
I'm here to write you after about 1.5 hour of hard debugging.
First of all, these are the interested files:
/project/app/utils.py
from django.core.mail import EmailMultiAlternatives
import threading
class EmailThread(threading.Thread):
def __init__(self, subject, body, from_email, recipient_list, fail_silently, html):
self.subject = subject
self.body = body
self.recipient_list = recipient_list
self.from_email = from_email
self.fail_silently = fail_silently
self.html = html
threading.Thread.__init__(self)
def run(self):
msg = EmailMultiAlternatives(self.subject, self.body, self.from_email, self.recipient_list)
if self.html:
msg.attach_alternative(self.html, "text/html")
print "sending message"
msg.send(self.fail_silently)
print "sent."
def send_html_mail(subject, body, from_email, recipient_list, fail_silently=False, html=None, *args, **kwargs):
EmailThread(subject, body, from_email, [recipient_list], fail_silently, html).start()
/project/app/views.py
[...]
import utils
def my_view(request):
[...]
utils.send_html_mail('subject', '<h1>cool things.</h1>', 'Test <[email protected]>', '[email protected]', html='<h1>cool things.</h1>')
/project/app/settings.py
# I use Amazon SES
[...]
EMAIL_BACKEND = 'backends.smtp.SSLEmailBackend'
EMAIL_HOST = 'amazon-server'
EMAIL_PORT = 465
EMAIL_HOST_USER = 'user'
EMAIL_HOST_PASSWORD = 'pass'
EMAIL_USE_TLS = True
[...]
/project/backends/smtp.py
# taken from https://gist.github.com/1486891
import smtplib
from django.core.mail.utils import DNS_NAME
from django.core.mail.backends.smtp import EmailBackend
class SSLEmailBackend(EmailBackend):
def open(self):
if self.connection:
return False
try:
self.connection = smtplib.SMTP_SSL(self.host, self.port,
local_hostname=DNS_NAME.get_fqdn())
if self.username and self.password:
self.connection.login(self.username, self.password)
return True
except:
if not self.fail_silently:
raise
Ok, now the problem:
in localhost:
- sending the email from the view works
- sending the email from the django shell works
in the deploy app on my server:
- sending the email from the view DOESN'T WORKS
- sending the email from the django shell works
Django shell output in localhost:
# utils.send_html_mail('subject', '<h1>cool things.</h1>', 'Test <[email protected]>', '[email protected]', html='<h1>cool things.</h1>')
sending email
sent.
Django shell output in deploy app:
# utils.send_html_mail('subject', '<h1>cool things.</h1>', 'Test <[email protected]>', '[email protected]', html='<h1>cool things.</h1>')
sending email
Same code, same commit. The problem is in the method msg.send(self.fail_silently)
just before the print "sent."
probably, but what is it? I don't have ideas.
And you?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您是否使用 --enable-threads 在 uWSGI 中启用了线程?
have you enabled threads in uWSGI with --enable-threads ?
由于
threading
存在uWSGI
的激活问题,您可以尝试将其添加到应用程序的 uwsgi 配置中:这样您的代码将在子进程分叉后加载。
As the
threading
having activating issue withuWSGI
you can try to add this to your app's uwsgi configuration:So your code will be loaded after child workers forked.