是否可以在生成500时向django发送给管理员的电子邮件中添加标题?

时间:2012-01-06 02:42:13

标签: python django email

我正在使用第三方发送电子邮件,他们允许我通过在我通过它发送的电子邮件中添加标题来对我的电子邮件进行分类。

是否可以在发送之前向异常电子邮件添加标头?或者至少,我将通过捕获中间件中的异常来管理发送电子邮件,但是如何生成好的电子邮件响应django发送给我500?

编辑:我知道如何向电子邮件添加标题,我知道如何通过中间件处理异常。我感兴趣的是如何生成django在异常时发送的相同电子邮件,以便我可以添加标题。

1 个答案:

答案 0 :(得分:8)

  1. 子类AdminEmailHandler (在django.utils.log中定义)。
  2. 相应地配置logging
  3. 以下是AdminEmailHandler的工作原理:

    class AdminEmailHandler(logging.Handler):
        """An exception log handler that emails log entries to site admins.
    
        If the request is passed as the first argument to the log record,
        request data will be provided in the email report.
        """
    
        def __init__(self, include_html=False):
            logging.Handler.__init__(self)
            self.include_html = include_html
    
        def emit(self, record):
            try:
                request = record.request
                subject = '%s (%s IP): %s' % (
                    record.levelname,
                    (request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS and 'internal' or 'EXTERNAL'),
                    record.msg
                )
                filter = get_exception_reporter_filter(request)
                request_repr = filter.get_request_repr(request)
            except:
                subject = '%s: %s' % (
                    record.levelname,
                    record.getMessage()
                )
                request = None
                request_repr = "Request repr() unavailable."
    
            if record.exc_info:
                exc_info = record.exc_info
                stack_trace = '\n'.join(traceback.format_exception(*record.exc_info))
            else:
                exc_info = (None, record.getMessage(), None)
                stack_trace = 'No stack trace available'
    
            message = "%s\n\n%s" % (stack_trace, request_repr)
            reporter = ExceptionReporter(request, is_email=True, *exc_info)
            html_message = self.include_html and reporter.get_traceback_html() or None
            mail.mail_admins(subject, message, fail_silently=True, html_message=html_message)
    

    仅供参考:我之前的回答。

    1. 创建自定义中间件:从https://code.djangoproject.com/browser/django/trunk/django/middleware/common.py中的CommonMiddleware中获取灵感(查看process_response
    2. 根据https://code.djangoproject.com/browser/django/trunk/django/core/mail/message.py
    3. 创建一个功能 send_mail_with_exception_header

      以下是一个例子:

      # Custom middleware
      
      class MyErrorMiddleware(object):
          def process_response(self, request, response):
              if response.status_code == 404:
                  domain = request.get_host()
                  referer = request.META.get('HTTP_REFERER', None)
                  is_internal = _is_internal_request(domain, referer)
                  path = request.get_full_path()
                      if referer and not _is_ignorable_404(path) and (is_internal or '?' not in referer):
                          ua = request.META.get('HTTP_USER_AGENT', '<none>')
                          ip = request.META.get('REMOTE_ADDR', '<none>')
                          mail_error("Broken %slink on %s" % ((is_internal and 'INTERNAL ' or ''), domain),
                              "Referrer: %s\nRequested URL: %s\nUser agent: %s\nIP address: %s\n" \
                                        % (referer, request.get_full_path(), ua, ip),
                                        fail_silently=True)
                      return response
      
      # Custom mail_error function
      
      def mail_error(subject, message, fail_silently=False, connection=None,
                        html_message=None):
          """Sends a message to the managers, as defined by the MANAGERS setting."""
          if not settings.MANAGERS:
              return
      
          # put your extra headers here
          mail = EmailMultiAlternatives(u'%s%s' % (settings.EMAIL_SUBJECT_PREFIX, subject),
                      message, settings.SERVER_EMAIL, [a[1] for a in settings.MANAGERS],
                      connection=connection, header={})
          mail
          if html_message:
              mail.attach_alternative(html_message, 'text/html')
          mail.send(fail_silently=fail_silently)