How can I log all outgoing email in Django?

前端 未结 4 2250
被撕碎了的回忆
被撕碎了的回忆 2021-02-20 00:28

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 th

相关标签:
4条回答
  • 2021-02-20 00:55

    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)
    
    0 讨论(0)
  • 2021-02-20 00:57

    Django offers custom E-Mail backends, you can write one on your own.

    0 讨论(0)
  • 2021-02-20 01:05

    Since the OP asked about logging and not about saving to DB, here's a middleware that does that:

    import django.core.mail.backends.smtp
    import logging
    
    logger = logging.getLogger(__name__)  # or you could enter a specific logger name
    
    class LoggingBackend(django.core.mail.backends.smtp.EmailBackend):
    
      def send_messages(self, email_messages):
        try:
            for msg in email_messages:
                logger.info(u"Sending message '%s' to recipients: %s", msg.subject, msg.to)
        except:
            logger.exception("Problem logging recipients, ignoring")
    
        return super(LoggingBackend, self).send_messages(email_messages)
    

    and then in your settings.py:

    EMAIL_BACKEND = 'whereiputit.LoggingBackend'
    
    0 讨论(0)
  • 2021-02-20 01:08

    I do not know if there exists a module that works this way, but writing a custom one is a piece of cake. Just create a separate model and every time you send an email, create a new instance ( use a custom method for email sending ). Then, link this model with the admin and bingo..

    0 讨论(0)
提交回复
热议问题