2009-06-06 10 views
2

J'utilise django.core.mail.EmailMultiAlternatives lors de l'envoi d'e-mails à partir de mon application django dans le but de m'assurer que le message est déclassé en texte si le Le client de messagerie ne supporte pas HTML.Django EmailMultiAlternatives et l'affichage du courrier HTML dans Outlook 2003 sur Win2003

Voici ma méthode send_email:

def send_email(self, from_address, to_list, subject, msg_text, msg_html): 
     subject=subject.replace('\r','').replace('\n',' ') 
     self.msg = EmailMultiAlternatives(subject, msg_text, from_address, to_list) 
     self.msg.attach_alternative(msg_html, "text/html") 
     self.msg.content_subtype = "html" 
     self.msg.send() 

Il fonctionne très bien avec Gmail, Hotmail et bien d'autres clients de messagerie électronique - affichant le contenu HTML sans problème. Mais il ne sera pas afficher le contenu HTML dans Outlook 2003 en cours d'exécution sur Win2003 - juste la version texte.

Si je mets avec force le code HTML dans le EmailMultiAlternatives appel, à savoir l'utilisation msg _html instead of msg _TEXT comme ceci:

self.msg = EmailMultiAlternatives(subject, msg_html, from_address, to_list) 

il fonctionne correctement dans tous les clients; mais cela signifie qu'il n'y a pas de retour de texte pour les clients qui ne supportent pas HTML ou (plus probablement) qui ont désactivé le support pour cela.

Je pense qu'il est utile de mentionner que l'e-mail est généré sur une application django fonctionnant sous Mac OS X (juste au cas où il s'agirait de différences de terminaison de ligne entre les systèmes d'exploitation).

Je vois que people using other languages ont eu des problèmes similaires avec perspectives ...

Je me demande si quelqu'un a une idée de perspectives Pourquoi se comporter différemment et s'il est simple correctif qui peut être appliqué dans mon code?

Répondre

5

Je n'ai pas d'installation Outlook disponible pour tester ceci, donc je m'interroge sur la raison de la cinquième ligne de votre fonction.

self.msg.content_subtype = "html"

je ne sais pas beaucoup sur internals email multipart, mais sur mon système cette ligne provoque les deux parties du message ont un type de contenu text/html. L'omettre produit un message avec "Content-Type: text/plain" dans la première partie et "Content-Type: text/html" dans la seconde.

Dans tous les cas, l'une des réponses à la question sur Java mentionne que le jeu de caractères est remplacé par iso-8859-1. Je pense que vous devriez être capable de le faire avec django.core.mail.

La classe EmailMessage (dont hérite EmailMultiAlternatives) possède un attribut nommé "encoding" qui définit le jeu de caractères à utiliser. Par défaut, il est None, donc le jeu de caractères par défaut de utf-8 (à moins qu'il ne soit surchargé dans les paramètres) est utilisé à la place.

En d'autres termes, ajouter quelque chose comme ce qui suit avant la ligne d'émission dans la fonction indiquée dans la question:

self.msg.content_subtype = "iso-8859-1"

Malheureusement, cela ne concerne que l'encodage spécifié sur la première partie (msg_text dans la fonction au dessus). La fonction qui attache le contenu alternatif ne semble pas utiliser l'attribut de codage. Je ne suis pas sûr que ce soit la bonne approche, mais j'ai sous-classé EmailMultiAlternatives pour remplacer la fonction concernée et cela a semblé fonctionner.

class EmailMultiAlternativesWithEncoding(EmailMultiAlternatives): 
    def _create_attachment(self, filename, content, mimetype=None): 
     """ 
     Converts the filename, content, mimetype triple into a MIME attachment 
     object. Use self.encoding when handling text attachments. 
     """ 
     if mimetype is None: 
      mimetype, _ = mimetypes.guess_type(filename) 
      if mimetype is None: 
       mimetype = DEFAULT_ATTACHMENT_MIME_TYPE 
     basetype, subtype = mimetype.split('/', 1) 
     if basetype == 'text': 
      encoding = self.encoding or settings.DEFAULT_CHARSET 
      attachment = SafeMIMEText(smart_str(content, 
       settings.DEFAULT_CHARSET), subtype, encoding) 
      # original text being replaced above (not last argument) 
      # attachment = SafeMIMEText(smart_str(content, 
      #  settings.DEFAULT_CHARSET), subtype, settings.DEFAULT_CHARSET) 
     else: 
      # Encode non-text attachments with base64. 
      attachment = MIMEBase(basetype, subtype) 
      attachment.set_payload(content) 
      Encoders.encode_base64(attachment) 
     if filename: 
      attachment.add_header('Content-Disposition', 'attachment', 
            filename=filename) 
     return attachment

Je ne suis pas sûr si le « smart_str (contenu, settings.DEFAULT_CHARSET) » partie devrait également faire référence à « encodage » plutôt que « settings.DEFAULT_CHARSET », mais c'est le texte de manipulation corps du message est écrit (django. core.mail.EmailMessage.message).Comme je l'ai dit, je n'ai pas Outlook, donc je ne peux pas réellement tester l'aspect Outlook, mais il semble changer le jeu de caractères en iso-8859-1 pour les deux parties.

+0

Je n'ai pas d'Outlook à tester non plus, mais +1 pour l'effort! –

+1

Votre premier instinct - que je ne devrais pas jouer avec content_subtype - était correct. Supprimer cela de ma fonction rend correctement le HTML dans Outlook 2003 et les autres clients de messagerie. Je pense que la documentation de Django sur l'envoi de courriels pourrait bénéficier soit de la suppression de la mention à content_subtype, soit de la façon de l'utiliser. J'ai supposé que depuis Outlook pourrait gérer un type de contenu alternatif; Je devrais utiliser le content_subtype = 'html'. Évidemment, ce n'est pas le cas et cela est contraire à ce que j'essayais d'accomplir. Merci beaucoup pour le contrôle de santé mentale. – cethegeek

+0

N'utilisez pas 'content_subtype =" iso-8859-1 "'! Il va juste mettre le type mime à 'text/iso-8859-1' qui est évidemment un non-sens, et alors votre message sera vide avec une pièce jointe appelée' noname' contenant le message réel. – Timmmm

Questions connexes