3
votes

I want to use send_mail in django, however it doesn't send any email. Here is my settings:

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_HOST_USER = '[email protected]'
EMAIL_HOST_PASSWORD = 'MY-GMAIL-PASSWORD'
EMAIL_PORT = 465
EMAIL_USE_TLS = False
EMAIL_USE_SSL = True
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
SERVER_EMAIL = DEFAULT_FROM_EMAIL

Then, I run python manage.py shell:

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

subject = 'Test Subject'
message = 'Test Message'
email_from = settings.EMAIL_HOST_USER
recipient_list = ['[email protected]']
send_mail(subject, message, email_from, recipient_list, fail_silently=False)

It doesn't send the email and it prints:

Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: Test Subject
From: [email protected]
To: [email protected]
Date: Mon, 09 Dec 2019 21:02:16 -0000
Message-ID: <157592533640.18842.5494330274157836181@thinkpad-e560>

Test Message
-------------------------------------------------------------------------------
1

which seems to have no errors. Why doesn't it send the email? What is wrong? Why doesn't it log any errors?

Following this page, I've tried a pure python way and it works fine:

import smtplib, ssl

smtp_server = "smtp.gmail.com"
port = 465
sender_email = "[email protected]"
password = 'MY-GMAIL-PASSWORD'
receiver_email = '[email protected]'
context = ssl.create_default_context()
server = smtplib.SMTP_SSL("smtp.gmail.com", port, context=context)
server.login(sender_email, password)
server.sendmail(sender_email, receiver_email, 'Test Message')

As I mentioned, this pure python way works fine! I'm confused.

What did I do wrong?

2
You need to pass fail_silently=True, see the docs for send_mail.Daniel Roseman
Thanks! I tried with "fail_silently=False". Nothing changed. I will edit my question to include "fail_silently=False" @DanielRosemanHsnVahedi
If calling send_mail is outputting to the console then you probably have your email backend set to 'django.core.mail.backends.console.EmailBackend'. Are you certain you have the smtp backend in your settings?Iain Shelvington
@DanielRoseman You mean "fail_silently=False", right?HsnVahedi
@IainShelvington is probably right. If you are seeing your email output in the console then you must have the console.EmailBackend configured. Print the value of settings.EMAIL_BACKEND just before calling send_mailivissani

2 Answers

6
votes

Thanks to @IainShelvington and @ivissani, I've figured it out. I use wagtail cms on top of django and created the project using "wagtail start mysite". for more information see this.

in wagtail standard project structure, there are base.py, dev.py and production.py instead of settings.py.

The Email settings was in base.py but in dev.py, EMAIL_BACKEND was overwritten. This is the dev.py when you create a django project using wagtail:

from .base import *

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'MY-SITE-KEY'

# SECURITY WARNING: define the correct hosts in production!
ALLOWED_HOSTS = ['*'] 

EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'


try:
    from .local import *
except ImportError:
    pass

So I fixed the problem by removing EMAIL_BACKEND from dev.py

0
votes

Start your python file with this:

import os
import sys
import django
django.setup()

# rest of your code

from django.conf import settings imports your settings but it doesn't set it as os environment.

os.environ['DJANGO_SETTINGS_MODULE'] = 'settings' - this also should work