'DbBackend' 对象没有属性 'use_ssl' django

'DbBackend' object has no attribute 'use_ssl' django

我有一个版本为 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

这可能是什么问题?

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

的新实施不兼容

如果您 post DbBackend 实现,我可以给您更详细的答案,但我的猜测是您覆盖了 EmailBackend.__init__ 而没有调用 super(DbBackend, self).__init__ .

编辑:您确实没有在 EmailBackend.__init__ 中调用 super(DbBackend, self).__init__ 而是 super(EmailBackend, self).__init__.

DbBackend__init__ 版本实际上是 Django 1.6 版本 EmailBackend.__init__ 的 copy/paste,没有锁实例化。

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

我不知道你为什么要摆脱锁定,但如果你要保留它,DbBackend 的实现将很简单:

class DbBackend(EmailBackend):
    def send_messages(self, email_messages):           
        if not email_messages:
            return
        for message in email_messages:
            msg = Message()
            msg.email = message
            msg.save()

        super(DbBackend, self).send_messages(email_messages)

它不会在 Django 进一步升级时中断。