python - Django send_mail 使用 RequestFactory 给出 NoneType 错误,但在视图之外运行代码时没有(包括测试代码)
问题描述
所以我在生产中遇到了我的网站的问题,并认为这是 Nginx 在生产中的问题。但我把它归结为另一个问题,我不太清楚如何定义。
send_mail
手头的问题是在 Django (1.10.x) 中使用该函数时。当我从终端运行我的函数代码时,我可以完美地发送电子邮件,只需在 python shell 中输入它即可。但是当我尝试使用 RequestFactory 运行它并使用请求运行给定的函数时,我得到了一个奇怪的错误。
我的终端屏幕上的这个错误比我在我的网站上收到的空白 500 服务器错误要清楚得多。
我尝试了不同的电子邮件设置,甚至在设置中将电子邮件后端更改为控制台,但没有任何效果。
打开我的外壳后有效的代码./manage.py shell_plus
>>> from django.core.mail import send_mail
>>> name = 'Test User'
>>> contact_email = 'testing@test.com'
>>> contact_phone = '123-456-7890'
>>> subject = 'Message from: %s, %s' % (name, contact_phone)
>>> message = 'This is a test being sent from the backend console.'
>>> to = 'user@test.com' # changed for anonymity
>>> send_mail(subject, message, contact_email, [to], fail_silently=False)
>>> 1 # this is what's returned
不起作用的代码
>>> from django.test import RequestFactory
>>> factory = RequestFactory()
>>> from views import contact # the view that runs my send_mail function
>>> request = factory.get(contact)
>>> request.method = 'POST' # needs to be POST method to trigger my view function that triggers the email function
>>> contact(request) # this is where things go south
让我在发布我的错误之前澄清一些事情。运行时contact(request)
,它会触发一个调用的函数,该函数包含与上述工作段代码contact_form
完全相同的代码。
这是我回来的冗长错误,因此,我不知所措。
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/root/test/website/views.py", line 46, in contact
request = utils.contact_form(request)
File "/root/test/website/utils.py", line 20, in contact_form
contact_phone = '123-456-7890'
File "/root/test/local/lib/python2.7/site-packages/django/core/mail/__init__.py", line 62, in send_mail
return mail.send()
File "/root/test_env/local/lib/python2.7/site-packages/django/core/mail/message.py", line 348, in send
return self.get_connection(fail_silently).send_messages([self])
File "/root/test_env/local/lib/python2.7/site-packages/django/core/mail/backends/smtp.py", line 111, in send_messages
sent = self._send(message)
File "/root/test_env/local/lib/python2.7/site-packages/django/core/mail/backends/smtp.py", line 125, in _send
message = email_message.message()
File "/root/test_env/local/lib/python2.7/site-packages/django/core/mail/message.py", line 307, in message
msg = SafeMIMEText(self.body, self.content_subtype, encoding)
File "/root/test_env/local/lib/python2.7/site-packages/django/core/mail/message.py", line 214, in __init__
MIMEText.__init__(self, _text, _subtype=_subtype, _charset=_charset)
File "/usr/lib/python2.7/email/mime/text.py", line 30, in __init__
self.set_payload(_text, _charset)
File "/root/test_env/local/lib/python2.7/site-packages/django/core/mail/message.py", line 224, in set_payload
for l in payload.splitlines()
AttributeError: 'NoneType' object has no attribute 'splitlines'
错误后的小测试
所以我注意到了这一行:File "/root/test/website/utils.py", line 20, in contact_form
contact_phone = '123-456-7890'
并决定在函数中将其注释掉。我收到了完全相同的错误,只是#
在该contact_phone
行之前。
我什至完全删除了该contact_phone
行,它只是在同一错误中显示代码的下一行。
编辑
request
如果有任何帮助,这里是细分
>>> request.environ
{u'HTTP_COOKIE': u'', u'wsgi.multithread': False,
u'SCRIPT_NAME': u'',
u'wsgi.input': <django.test.client.FakePayload object at 0x7f12e169d850>,
u'REQUEST_METHOD': 'GET',
u'PATH_INFO': u'<function contact at 0x7f12e226a050>',
u'SERVER_PROTOCOL': 'HTTP/1.1',
u'QUERY_STRING': '',
u'wsgi.version': (1, 0),
u'SERVER_NAME': 'testserver',
u'REMOTE_ADDR': '127.0.0.1',
u'wsgi.run_once': False, u'wsgi.errors': <_io.BytesIO object at 0x7f12e16329b0>,
u'wsgi.multiprocess': True,
u'wsgi.url_scheme': 'http',
u'SERVER_PORT': '80', u'CSRF_COOKIE': u'IicQMalE3nSO682lHcZQG3kI51X5f1P1wQwfFzLdv3EFjM2KdnUrlayjjsbrsOct',
u'CSRF_COOKIE_USED': True}
更多测试
所以我已经移动了我用来发送邮件的函数,并将它直接放在视图函数中。但我什至没有将它作为一个函数本身,而只是一些变量分配(带有测试值)和 send_mail 函数本身。仍然收到 500 错误,这甚至没有尝试解析 HTML 表单中的信息。
解决方案
你用RequestFactory
错了。它接受 URL 路径(例如,/
),而不是您传递给它的视图函数。您需要使用工厂生成请求对象,然后将其传递给您的视图函数。像这样的东西:
from django.test import RequestFactory
request = RequestFactory().post('/') # Use post() instead of get() if you're testing a post request
# Pass this request object to your view function
response = contact(request)
文档中有关如何使用的示例RequestFactory
在这种情况下值得一看。
推荐阅读
- node.js - Socket.io 使用使用 Node.JS 集群和 PM2
- javascript - 使用自定义选择显示特定内容
- java - Gmail Api 给出了超出用户速率限制的错误
- mysql - 光滑的 mysql 流,以避免 GC 和 OOM 问题
- rust - 在 rust 中修改 hashmap 中的结构向量。return 语句中的显式生命周期注释
- java - Selenium Click 方法在元素边界外执行点击
- jenkins - 如何在詹金斯中为不同环境(测试、产品和质量保证)使用具有多个值的变量
- c++ - C++中赋值运算符重载错误
- ios - FirebaseMLVisionTextModel 已被弃用,取而代之的是 MLKitTextRecognition
- javascript - PostCSS 使用 mixins 动态生成类