繁体   English   中英

Django send_mail在RequestFactory中给出NoneType错误,但在视图外运行代码时不给出(包括测试代码)

[英]Django send_mail giving NoneType Error with RequestFactory, But Not When Running Code Outside of Views (Test Code Included)

因此,我的网站在生产中遇到了问题,并认为在生产中与Nginx有关。 但是我将其归结为另一个我不确定如何定义的问题。

当前的问题是在Django(1.10.x)中使用send_mail函数时。 从终端运行功能代码时,只需在python shell中键入它,我就可以完美地发送电子邮件。 但是,当我尝试使用RequestFactory运行它并使用请求运行给定函数时,出现一个奇怪的错误。

终端屏幕上的此错误比我在网站上收到的空白500服务器错误要清晰得多。

我尝试了不同的电子邮件设置,甚至将电子邮件后端更改为设置中的控制台,但没有任何效果。

打开我的shell后,可以工作的代码 ./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示例

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM