1

I have a csv which contains more than 1000 emails to which django has to send an email. But when i uploaded the csv file with more than 1000 records it was displaying me the below error

File "/user/Envs/project/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 112, in get_response
  response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/user/Envs/project/local/lib/python2.7/site-packages/django/contrib/admin/views/decorators.py", line 17, in _checklogin
  return view_func(request, *args, **kwargs)
File "/user/apps/project_webapp/appy/customadmin/views.py", line 1131, in send_monthly_email
  connection.send_messages(emails)
File "/user/apps/project_webapp/appy/mailer/backend.py", line 57, in send_messages
  sent = self._send(message)
File "/user/Envs/project/local/lib/python2.7/site-packages/django/core/mail/backends/smtp.py", line 110, in _send
  self.connection.sendmail(from_email, recipients, message.as_bytes())
File "/usr/lib/python2.7/smtplib.py", line 735, in sendmail
  raise SMTPRecipientsRefused(senderrs)

But when i run the same csv file with just 10 emails in it and it worked without any error

Below are my codes

settings.py

EMAIL_BACKEND = "mailer.backend.DbBackend"
EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.sendgrid.net' #'smtp.gmail.com'
EMAIL_HOST_USER = 'xxxxx'
EMAIL_HOST_PASSWORD = 'xxxxxx'
EMAIL_PORT = '587'
EMAIL_SUBJECT_PREFIX = 'xxxxxxxxx'
DEFAULT_FROM_EMAIL = 'some@example.com'

I want to save the message that django was going to send in my database before it sends and hence i had written my custom email backend

DbBackend.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

        #By default Django has this self._lock variable active, we have to deactivate it in 
        #order to save the messages in our database, without deactivating the message objects
        #will be locked and django doesn't allow to save the locked objects  

        # 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

        # Save the messages to your database
        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

views.py

from django.core import mail

def send_monthly_email(request):
    if request.method == "POST":
        form = MonthlyEmailForm(request.POST, request.FILES)
        if form.is_valid():
            subject = request.POST.get('subject')
            message = request.POST.get('message')
            from_email = 'orders@example.com'
            recipient_list = request.FILES.get('recipient_list')
            input_file = csv.DictReader(recipient_list)
            connection = mail.get_connection()
            emails = []
            for row in input_file:
                 recipient = row.get('%s Recipients' % state).strip()
                 email = mail.EmailMessage(subject, message, from_email, [recipient,])
                 email.content_subtype = "html"
                 emails.append(email)
            connection.open()
            connection.send_messages(emails)
            connection.close()
            return HttpResponseRedirect('/admin/')
        else:
            response = RequestContext(request, {"form": form})
            return render_to_response('customadmin/monthly_email_form.html', response)
   data = {.................}
   form = MonthlyEmailForm(initial=data)
   response = RequestContext(request, {"form": form})
   return render_to_response('customadmin/monthly_email_form.html', response)

So with my above codes when i tried to send messages to 1000 emails it was displaying the mentioned error, and by taking a chance i thought that there was an error in my DBbackend.py file and hence replaced the setting EMAIL_BACKEND = "mailer.backend.DbBackend" to EMAIL_BACKEND = django.core.mail.backends.smtp.EmailBackend i.e., the default django backend and even though the am receiving the same error

I have google a lot on many posts but couldn't able to get this work, can anyone solve this error ? and why it was throwing error when trying to send emails to 1000 email id's at once ? and why it was sending successfully to 10 email id's ?

Thanks in Advance

Shiva Krishna Bavandla
  • 25,548
  • 75
  • 193
  • 313

1 Answers1

0

Try as_string() instead of as_bytes().

Unihedron
  • 10,902
  • 13
  • 62
  • 72