1. Branko Vukelic
  2. django-topic-email




Topic-based mailing system for Django with support for automatic HTML-to-text conversion and multiple email setting profiles.


django-topic-email allows developers to send emails to different addresses based on 'topics', which are defined in the database. Each topic is simply a name-address pair. Names can have more than one email address associated with them. Think of topics as of mailing lists. Instead of sending emails to multiple hard-coded addresses, we send emails to named topics, and the messages are sent to whatever addresses happen to be associated with the given topic's name.

django-topic-email also supports multiple email configuration profiles. You can stick to using Django's default email configuration API, or you can use the alternative syntax similar to the one used for database configuration. Django's email configuration settings are automatically converted to the 'default' profile internally, though.

The email module contains functions for converting HTML email to plain-text, and functions for sending out email messages with support for Django templates.


BeautifulSoup4 is required for this app. Install 4.0 or higher.

Email configuration profiles

Just like database configuration, an alternative syntax for multiple email host configurations is supported. The syntax different from the Django email configuration syntax, and uses all-lowercase keys.

Here's an example using Mandrill for sending messages by default, and using Gmail for sending messages supposedly meant for managers:

    'default': {
        'host': 'smtp.mandrillapp.com',
        'username': 'humptydumpty@test.com',
        'password': 'abc123',
        'port': 587,
        'use_tls': True
    'managers': {
        'host': 'smtp.gmail.com',
        'username': 'admins@gmail.com',
        'password': 'my password',
        'port': 465,
        'use_tls': True

Instead of the 'default' key, you can also configure the email settings that are normally used in Django which would then be used as the 'default' profile.

email.send_mail(subject, from_email, to, template, [data={}, text_only=False, reply_to=None, send_separately=False, headers={}, profile='default']

To send an email, use the email.send_mail method. Compared to Django, this function has quite a few additional arguments.

  • subject: Message subject.
  • from_email: Sender email. There are no defaults.
  • to: Recipient address. It can either be a single string or a list.
  • template: Name of the Django template for this email.
  • data: Dict used as context in templates. When send_separately argument is True, the dict may be used to map individual recipient addresses to data meant for each recipient. Default is empty dict.
  • text_only: Do not send the HTML part if True.
  • reply_to: The "Reply-to" address.
  • send_separately: When there is more than one recipient, send messages separately, one by one, instead of using a "To" field with multiple addresses.
  • headers: Any extra headers that should be used in the messages.
  • profile: The configuration profile.

The simples case is sending a single message to a recipient:

from topic_email.email import send_mail

    subject='Test subject',

It is possible to send to multiple recipients one by one. Django will reuse the existing connection when sending multiple messages separately, but there will still be a SMTP overhead for sending a large numbers in bulk.

# Prepare a separate dict for each user, possibly with customized data
data = {
    'ted@example.com': { .... },
    'bob@example.com': { .... },
    'jan@example.com': { .... },
    # ....

    subject='Test multiple recipients',


Topics are implemented with a very simple model topic_email.Topic. The model supports South migrations, so you should migrate this app whenever you install or update it.

Setting up topics

The topics are set up using the TOPICS setting. This setting should be an iterable of 2-tuples like the ones used for choices argument in model fields. The first item in the tuple is the actual topic name that will be used to address a particular topic, and the second item is its human-readable label.


    ('user_reg', 'User registers on site'),
    ('user_del', 'User account removed'),
    # ....

Topic.send_mail(topic, *args, **kwargs)

The Topic model sports a single class method send_mail which takes a topic name as first argument, and arguments that are supported by email.send_mail function.