Django - Sending email works in shell, but not on localhost - ConnectionRefusedError

4.4k views Asked by At

I'm new to Django, but I have read on the order of 50 pages (mostly SO and Django documentation) and haven't found anything that quite works for my situation.

I'm merely trying to send an email via the send_mail function in Django; although I'm hoping to get this working through SMTP on Gmail, right now it doesn't even work via localhost. When I run my test_email.py file where I'm testing this send_mail function, I get the following error:

ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it

When I run this same send_mail call in the shell (via python manage.py shell), it's completely fine and displays the email just as I would expect. It's only once I try to run it in Django that the error pops up. Note that I get the above error no matter which permutation of the following 2 sets of settings I put in my settings.py file:

EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
EMAIL_HOST = 'localhost'
EMAIL_PORT = 1025
EMAIL_HOST_USER = '[email protected]'
EMAIL_HOST_PASSWORD = ''
EMAIL_USE_TLS = False

I've also played around with the following in my settings.py file, and various mixes of these settings with the previous set (though I guess I'm getting ahead of myself seeing how localhost isn't working):

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = '[email protected]' # Note I'm using my actual gmail address here in real life
EMAIL_HOST_PASSWORD = '****' # Note I'm using my actual gmail password here in real life

DEFAULT_FROM_EMAIL = '[email protected]' # Note I'm using my actual gmail address here in real life
SERVER_EMAIL = '[email protected]' # Note I'm using my actual gmail address here in real life

I'm running the following command in a CMD prompt off to the side when I try to run going the localhost route:

python -m smtpd -n -c DebuggingServer localhost:1025

Here's the test_email.py file I'm trying to run in Django, where I get the connection refused error:

from django.core.mail import send_mail,EmailMessage

from django.conf import settings
settings.configure()

# Create your tests here.

# Email test #1: send email from my personal email to myself
send_mail(
    'Email Test #1',
    'Test if I can send email from my personal Gmail account to another email account via Django project.',
    settings.EMAIL_HOST_USER,
    ['[email protected]'],
    fail_silently=False
    )

Any thoughts on why this isn't even working via localhost or suggestions on other things to try would be greatly appreciated.

Thanks!

4

There are 4 answers

1
Astik Anand On

I think there are some problem with gmail smtp service. Try using smtp service form sendgrid. It is also free for basic usage. I too was facing the same issue earlier.

In project settings.py

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.sendgrid.net'
EMAIL_HOST_USER = 'sendgridusername'
EMAIL_HOST_PASSWORD = 'sedgridpasseord'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
DEFAULT_FROM_EMAIL = '[email protected]'

still error

Try if `smtp` service is working on your server.
0
lmiguelvargasf On

The following configuration worked for me:

settings.py

EMAIL_HOST = 'smtp.sendgrid.net'
EMAIL_HOST_USER = 'apikey' # this is exactly the value 'apikey'
EMAIL_HOST_PASSWORD = 'sendgrid-api-key' # this is your API key
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
DEFAULT_FROM_EMAIL = '[email protected]' # this is the sendgrid email

I used this configuration, and it worked properly, and I strongly suggest using environment variables to fill EMAIL_HOST_PASSWORD and DEFAULT_FROM_EMAIL:

import os # this should be at the top of the file

# ...

EMAIL_HOST = 'smtp.sendgrid.net'
EMAIL_HOST_USER = 'apikey'
EMAIL_HOST_PASSWORD = os.getenv("EMAIL_HOST_PASSWORD", "")
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
DEFAULT_FROM_EMAIL = os.getenv("DEFAULT_FROM_EMAIL", "")

In order to send an email, use the following code:

from django.conf import settings
from django.core.mail import send_mail

send_mail('This is the title of the email',
          'This is the message you want to send',
          settings.DEFAULT_FROM_EMAIL,
          [
              settings.EMAIL_HOST_USER, # add more emails to this list of you want to
          ]
)
0
Matias Endres On

Try to enable this option in your google account after you make sure that your mail and password is right.

https://myaccount.google.com/lesssecureapps?pli=1

google blocks the access to insecure apps.

your code seems to be right!

0
Rami Alloush On

Make sure your settings are in the project settings.py NOT app settings.py as follows

EMAIL_HOST = 'localhost'
EMAIL_PORT = 1025
EMAIL_HOST_USER = ''
EMAIL_HOST_PASSWORD = ''
EMAIL_USE_TLS = False

note the empty string for EMAIL_HOST_USER I think this is your mistake

Once you run your virtual python SMTP using

python -m smtpd -n -c DebuggingServer localhost:1025

You will be able to send to your local smtp server with no problem. Source