pythondjangologgingpython-loggingdjango-email

How can I log all outgoing email in Django?


My Django application sends out quite a bit of emails and I've tried testing it thoroughly. However, for the first few months, I'd like to log all outgoing emails to ensure that everything is working smoothly.

Is there a Django module that allows me to do this and makes the outgoing emails visible through the administration panel?


Solution

  • I wrote a custom email backend which logs the stuff to a model.

    Here's my backend:

    from django.core.mail.backends.smtp import *
    from django.db import transaction
    
    from modules.common.models import *
    
    class LoggingEmailBackend(EmailBackend):
        """
        A wrapper around the SMTP backend that logs all emails to the DB.
        """
        def send_messages(self, email_messages):
        """
        A helper method that does the actual logging
        """
        with transaction.commit_on_success():
    
            for email_message in email_messages:
    
                email_record = Email.objects.create(
                    to='; '.join(email_message.recipients()),
                    subject=email_message.subject, body=email_message.body,
                )
    
                try:
                    return super(LoggingEmailBackend, self)._send(
                        email_message
                    )
                except:
                    email_record.ok = False
                    return False
                finally:
                    email_record.ok = True
                    return True
    

    Here's the model:

    class Email(models.Model):
        """
        Model to store all the outgoing emails.
        """
        when = models.DateTimeField(
            null=False, auto_now_add=True
        )
        to = models.EmailField(
            null=False, blank=False,
        )
        subject = models.CharField(
             null=False, max_length=128,
        )
        body = models.TextField(
            null=False, max_length=1024,
        )
        ok = models.BooleanField(
            null=False, default=True,
        )
    

    Here's my model:

    from django.contrib import admin
    
    from modules.common.models import *
    
    class EmailAdmin(admin.ModelAdmin):
        """
        Admin part for managing the the Email model
        """
        list_display = ['to', 'subject', 'ok',]
        list_filter = ['ok']
        readonly_fields = ['when', 'to', 'subject', 'body', 'ok']
        search_fields = ['subject', 'body', 'to']
    
        def has_delete_permission(self, request, obj=None):
            return False
    
        def has_add_permission(self, request):
            return False
    
    
    admin.site.register(Email, EmailAdmin)