Nazkter
Nazkter

Reputation: 1110

Django: Set E-Mail settings in view

I am trying to send a email using SMTP from Google. I already get to send a email putting the setting variables in the file "settings.py" but I need to configure these variables in a view and set them using my "Config" model.

This is my model code:

class Config(models.Model):
    email_sender    = models.CharField(max_length = 100, default = '', blank = True)
    email_password  = models.CharField(max_length = 30, default = '', blank = True)
    smtp_server     = models.CharField(max_length = 100, default = '', blank = True)
    smtp_port       = models.PositiveIntegerField(default = 587, blank = True)

This is my view code:

def send_custom_mail(request):
    config = Config.objects.get(pk = 1)
    EMAIL_HOST = config.smtp_server
    EMAIL_PORT = config.smtp_port
    EMAIL_HOST_USER = config.email_sender
    EMAIL_HOST_PASSWORD = config.email_password
    EMAIL_USE_TLS = True
    DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
    subject = 'test'
    msg = '<p>Test: <strong>Mensaje</strong>></p>'
    mail_from = config.email_sender
    mail_to = ['{}'.format(email)]
    from django.core.mail import EmailMessage
    email2send  = EmailMessage(subject, msg, mail_from, to=mail_to)
    email2send.content_subtype = "html"  # Main content is now text/html
    email2send.send()

My problem: The email is not sent when I set the variables in the view.

I need to configure these variables dinamically so I can't write it in the setting.py file.

Upvotes: 0

Views: 2048

Answers (3)

ramakrishna
ramakrishna

Reputation: 13

def email_sending(mail_subject, message,to, mail_obj=None):
if not mail_obj:
    try:

        mail_obj = AdminEMailsModel.objects.filter(default_email=True)[0]

    except Exception as e:
        print(e)
        try:
            if not mail_obj:
                mail_obj= AdminEMailsModel.objects.all()[0]

        except Exception as e:
            print(e)
            return
backend = EmailBackend(host=mail_obj.host_address, port=mail_obj.port_no, username=mail_obj.email,
                       password=mail_obj.password, use_tls=mail_obj.use_tls, fail_silently=False)
email = EmailMultiAlternatives(
    mail_subject, message, from_email=mail_obj.email, to=to, connection=backend
)

email.attach_alternative(message, 'text/html')
email.send()

return

directly you can call this function whenever you need to send an email to register email if this code is usefull to you please give up vote

Upvotes: 0

Rod Manning
Rod Manning

Reputation: 404

I'm a bit puzzled about having to override settings in a view; never seen a use case for it before.

Strategy I'd normally use would be to fall-back either to lower-level functions.

I'd suggest that you could achieve what you seem to need to by using the send_mail() function and get_connection().

Haven't tested this code, but think it would look like this:

from django.core import mail

connection = mail.get_connection(
    host = config.smtp_server,
    port = config.smtp_port,
    username = config.email_sender,
    password = config.email_password ,
    (... etc etc ...)
)

# Manually open the connection
connection.open()

# Send the message
subject = 'test'
msg = 'Test:Mensaje'
mail_to = ['[email protected]']
email2send  = EmailMessage(
    subject, 
    msg, t
    o=mail_to
    connection=connection
)

# Send the email using the custom connection
email2send.send()

# Close the connection
connection.close()

(Note the connection=connection when the EmailMessage is first setup to send the email via the custom connection.)

Django Email Backends docs explain this pretty well, and this seems a more straight-forward way to do it than overriding settings.

Upvotes: 2

Nazkter
Nazkter

Reputation: 1110

I found this solution, but I don't know if it is the best way to aproach this problem:

using this: https://docs.djangoproject.com/en/1.11/_modules/django/test/utils/#override_settings

In my view I overrride the setting variables:

from django.core.mail import EmailMessage
from django.test.utils import override_settings

@override_settings(EMAIL_HOST = Config.objects.get(pk = 1).smtp_server)
@override_settings(EMAIL_HOST_USER = Config.objects.get(pk = 1).email_sender)
@override_settings(EMAIL_PORT = Config.objects.get(pk = 1).smtp_port)
def send_custom_mail(request):
subject = 'test'
    msg = 'Test:Mensaje'
    mail_to = ['[email protected]']
    email2send  = EmailMessage(subject, msg, to=mail_to)
    email2send.content_subtype = "html"  # Main content is now text/html
    email2send.send()

in this aproach I use "django.test.utils" to put the decorator "@override_settings()" before the "send_custom_mail" function. It override the setting and let me send emails from a mail saved in a model called Config.

Actually, I'm not sure if it is the best aproach because the "django.test" module is meant to use in unit tests, but I wanted to share my solution.

Upvotes: 0

Related Questions