' DbBackend'对象没有属性' use_ssl' Django的

时间:2015-04-27 08:58:36

标签: django sendmail backend

我有一个版本为1.6.5的django应用程序并将其更新为django 1.8并在尝试发送电子邮件时出现以下错误

Traceback:
File "/Users/user/.virtualenvs/env/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  132.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/user/user_name/apps/proj/project_name/app_name/core/views.py" in contact_page
  54.       send_mail('Contact from web', body, 'Directories', ["info@project.com"], fail_silently=False)
File "/Users/user/.virtualenvs/env/lib/python2.7/site-packages/django/core/mail/__init__.py" in send_mail
  62.     return mail.send()
File "/Users/user/.virtualenvs/env/lib/python2.7/site-packages/django/core/mail/message.py" in send
  303.         return self.get_connection(fail_silently).send_messages([self])
File "/Users/user/user_name/apps/proj/project_name/app_name/mailer/backend.py" in send_messages
  50.         new_conn_created = self.open()
File "/Users/user/.virtualenvs/env/lib/python2.7/site-packages/django/core/mail/backends/smtp.py" in open
  46.         connection_class = smtplib.SMTP_SSL if self.use_ssl else smtplib.SMTP

Exception Type: AttributeError at /contact/
Exception Value: 'DbBackend' object has no attribute 'use_ssl'

并且视图是

def contact_page(request):
  if request.method == 'POST':
    form = ContactForm(request.POST)
    if form.is_valid():
      name = form.cleaned_data['name'].encode('utf8')
      phone = form.cleaned_data['phone']
      .....
      ....
      send_mail('Contact from web', body, 'Directories', ["info@project.com"], fail_silently=False)
      .......

backend.py

from django.core.mail.backends.smtp import EmailBackend
from mailer.models import Message
from django.conf import settings

class DbBackend(EmailBackend):

    def __init__(self, host=None, port=None, username=None, password=None,
                 use_tls=None, fail_silently=False, **kwargs):
        super(EmailBackend, self).__init__(fail_silently=fail_silently)
        self.host = host or settings.EMAIL_HOST
        self.port = port or settings.EMAIL_PORT
        if username is None:
            self.username = settings.EMAIL_HOST_USER
        else:
            self.username = username
        if password is None:
            self.password = settings.EMAIL_HOST_PASSWORD
        else:
            self.password = password
        if use_tls is None:
            self.use_tls = settings.EMAIL_USE_TLS
        else:
            self.use_tls = use_tls
        self.connection = None
        # self._lock = threading.RLock()

    def send_messages(self, email_messages):
        """
        Sends one or more EmailMessage objects and returns the number of email
        messages sent.
        """
        if not email_messages:
            return
        for message in email_messages:
            msg = Message()
            msg.email = message
            msg.save()
        # with self._lock:
        new_conn_created = self.open()
        if not self.connection:
            # We failed silently on open().
            # Trying to send would be pointless.
            return
        num_sent = 0
        for message in email_messages:
            sent = self._send(message)
            if sent:
                num_sent += 1
        if new_conn_created:
            self.close()
        return num_sent

这可能是什么问题?

1 个答案:

答案 0 :(得分:1)

问题是您的Django应用程序使用自定义电子邮件后端(由EMAIL_BACKEND设置指定),该自定义电子邮件后端显然是子类django.core.mail.backends.smtp.EmailBackend,并且该类已在Django 1.6和Django 1.8之间发生了变化。您的自定义电子邮件后端与django.core.mail.backends.smtp.EmailBackend的新实现不兼容。

如果您要发布DbBackend实施内容,我可以给您更详细的答案,但我的猜测是您在不调用EmailBackend.__init__的情况下覆盖super(DbBackend, self).__init__

修改:您确实没有在super(DbBackend, self).__init__但是EmailBackend.__init__中致电super(EmailBackend, self).__init__

DbBackend的{​​{1}}版本实际上是没有锁定实例化的__init__的Django 1.6版本的复制/粘贴。

解决您问题的最简单方法是不覆盖EmailBackend.__init__方法。如果您不想锁定,请不要在__init__中使用锁定,但要实例化。

我不知道你为什么要摆脱锁定,但如果你保留它,那么send_messages的实现就像这样简单:

DbBackend

它不会因Django的进一步升级而中断。