9
votes

I don't want to use email configuration fields in setting.py, i want to put them in to a model.

class Configuration(models.Model):
    email_use_tls = models.BooleanField(_(u'EMAIL_USE_TLS'),default=True)
    email_host = models.CharField(_(u'EMAIL_HOST'),max_length=1024)
    email_host_user = models.CharField(_(u'EMAIL_HOST_USER'),max_length=255)
    email_host_password = models.CharField(_(u'EMAIL_HOST_PASSWORD'),max_length=255)
    email_port = models.PositiveSmallIntegerField(_(u'EMAIL_PORT'),default=587)
    ....

What is the best practice to configure django.core.mail.send_mail behaviour? Should i copy send_mail code to my project? Thats not what i want.

4

4 Answers

19
votes

Very interesting question. It seems like this is already implemented in EmailMessage class.

First you need to configure email backend

from django.core.mail import EmailMessage
from django.core.mail.backends.smtp import EmailBackend


config = Configuration.objects.get(**lookup_kwargs)

backend = EmailBackend(host=config.host, port=congig.port, username=config.username, 
                       password=config.password, use_tls=config.use_tls, fail_silently=config.fail_silently)

Then just pass connection to EmailMessage

email = EmailMessage(subject='subj', body='body', from_email=from_email, to=to, 
             connection=backend)

Then send email :)

email.send()

Ofc if you want html or file attachments use EmailMultiAlternatives instead

2
votes

There is little error in the answer above (Andrey Nelubin's answer). No need to call get_connection(backend=backend). You should pass backend to the EmailMessage constructor, like this:

backend = EmailBackend(host=config.host, port=congig.port, username=config.username, 
                               password=config.password, use_tls=config.use_tls, fail_silently=config.fail_silently)
email = EmailMessage(subject='subj', body='body', from_email=from_email, to=to, 
                 connection=backend)

I can not add comment that answer and dicided to post new one. Please someone who have permissions move it there or correct the answer.

0
votes

I've used this method for a few years and love it. I've just published a package (django-des) to accomplish this using the methods in the other answers here.

This package installs a model (DynamicEmailConfiguration) and uses django-solo to give you a nice editing experience in the Django admin. It then provides an email backend you can use that will pull settings from that model in a similar way to what Andrey Nelubin recommended. It also gives you a nice little test email button at the top right of the Django Admin Panel.

To install it:

  • Install Django Dynamic Email Settings:

    $ pip install django-des
    
  • Add it to your `INSTALLED_APPS`:

    INSTALLED_APPS = (
        ...
        'django_des',
        ...
    )
    
  • Add the dynamic email configuration email backend to settings.py

    EMAIL_BACKEND = 'django_des.backends.ConfiguredEmailBackend'
    
  • To enable test email support, add Django DES's URL patterns:

    from django_des import urls as django_des_urls
    
    urlpatterns = [
        ...
        url(r'^django-des/', include(django_des_urls)),
    ]
    

Now you can visit 127.0.0.1:8000/admin/django_des/dynamicemailconfiguration/ and configure your email settings. You can send a test email from there too.

Once this is all done, you can use send_mail normally.

0
votes

You should create an object from EmailBackend:

I have been an answer in the previous stack overflow post.