【问题标题】:Django email attachements sends as "noname"以“无名”形式发送的 Django 电子邮件附件
【发布时间】:2013-03-19 10:16:18
【问题描述】:
from django.template import loader, Context
from django.core.mail import EmailMultiAlternatives, EmailMessage
from settings import ADBOARD_SETTINGS
import settings


def send_mail(mail_to, subj, message_dict, template_dict=False, mail_from=ADBOARD_SETTINGS['mail_from'], attach=False):

    if not isinstance(mail_to, list):
        mail_to = [mail_to]

    if template_dict:
        txt = loader.get_template(template_dict['txt'])
        html = loader.get_template(template_dict['html'])
        c = Context(message_dict or None)
        message_txt = txt.render(c)
        message_html = html.render(c)
        msg = EmailMultiAlternatives(subj, message_txt, mail_from, mail_to)
        msg.attach_alternative(message_html, "text/html")
    else:
        msg = EmailMessage(subj, message_dict, mail_from, mail_to)
    if attach:
        for one in attach:
            msg.attach(one[0], one[1], one[2])
    msg.send()

def contacts(request):
    from choices import ContactCategoryChoices

    if request.method == 'POST':
        form = ContactForm(request.POST, request.FILES)
        if form.is_valid():
            data = {
                'email': form.cleaned_data.get('email'),
                'subject': form.cleaned_data.get('subject'),
                'message': form.cleaned_data.get('message'),
                'category': int(form.cleaned_data.get('category'))
            }

            recievers = (
                (#recievers)

            emailList = list(dict(recievers)[data.get('category')])

            attaches = [(upload.name, upload.read(), upload.content_type) for upload in
                        [form.cleaned_data[attach] for attach in request.FILES]]
            send_mail(emailList, u'Письмо со страницы контактов', data, {
                'txt': 'home/contacts/txt.html',
                'html': 'home/contacts/html.html',
            }, mail_from=settings.SENDER_EMAIL, attach=attaches)
            messages.add_message(request, messages.SUCCESS, u'Сообщение отправлено')
            form = ContactForm()
    else:
        form = ContactForm()
    return render_to_response('home/contacts/index.html', {'form': form}, context_instance=RequestContext(request))

如果我添加一些文件 - 它们在附件中显示为“noname”……不仅是 gmail。 Django 1.3.1,utf-8 命名文件。 有没有机会在不转换为 ascii 的情况下使其工作?只要因为保存原始文件名而无法转换就很重要了。

更新:
同时标题似乎合法:

【问题讨论】:

  • 如果您已修复,请将解决方案作为答案发布并接受。

标签: django email gmail


【解决方案1】:

好的。用下面的代码弄明白了:

import mimetypes
from email import encoders
from email.header import Header
from email.mime.base import MIMEBase
from django.core.mail.message import DEFAULT_ATTACHMENT_MIME_TYPE

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)
        else:
            # Encode non-text attachments with base64.
            attachment = MIMEBase(basetype, subtype)
            attachment.set_payload(content)
            encoders.encode_base64(attachment)
        if filename:
            try:
                filename = filename.encode('ascii')
            except UnicodeEncodeError:
                filename = Header(filename, 'utf-8').encode()    # This is the important line
            attachment.add_header('Content-Disposition', 'attachment',
                                   filename=filename)
        return attachment

【讨论】:

    【解决方案2】:

    根据票证14964中的fix

    from django.core.mail import EmailMultiAlternatives
    import mimetypes
    from django.core.mail.message import DEFAULT_ATTACHMENT_MIME_TYPE
    
    class UnicodeEmailMultiAlternatives(EmailMultiAlternatives):
    
        def _create_attachment(self, filename, content, mimetype=None):
            """
            Overrides EmailMultiAlternatives method to allow UTF8 filenames as attachments.
            """
            if mimetype is None:
                mimetype, _ = mimetypes.guess_type(filename)
                if mimetype is None:
                    mimetype = DEFAULT_ATTACHMENT_MIME_TYPE
            attachment = self._create_mime_attachment(content, mimetype)
            if filename:
                try:
                    filename = filename.encode('ascii')
                except UnicodeEncodeError:
                    filename = ('utf-8', '', filename.encode('utf-8'))
                attachment.add_header('Content-Disposition', 'attachment',
                                      filename=filename)
            return attachment
    

    【讨论】:

      猜你喜欢
      • 2022-01-17
      • 1970-01-01
      • 2011-06-16
      • 2017-06-11
      • 1970-01-01
      • 1970-01-01
      • 2016-06-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多