用python中的smtplib将django文件字段内容作为电子邮件附件发送?

用python中的smtplib将django文件字段内容作为电子邮件附件发送?,python,django,email,smtplib,filefield,Python,Django,Email,Smtplib,Filefield,我想发送带有各种附件的电子邮件。这些附件作为文件字段存储在django模型中。我设法创建邮件并发送附件,但附件是空的,而我希望它包含文件字段内容。谢谢你的帮助 def sendEmailHtml(fromaddr, toaddrs, body, subject, attachmentFiles=[]): """ Sends HTML email using hardcoded server parameters attachmentFiles is a list of File

我想发送带有各种附件的电子邮件。这些附件作为文件字段存储在django模型中。我设法创建邮件并发送附件,但附件是空的,而我希望它包含文件字段内容。谢谢你的帮助

def sendEmailHtml(fromaddr, toaddrs, body, subject, attachmentFiles=[]):
    """ Sends HTML email using hardcoded server parameters

    attachmentFiles is a list of FileFields
    """
    # Create message container - the correct MIME type is multipart/alternative.
    msg = MIMEMultipart('alternative')
    msg['From'] = fromaddr
    msg['To'] = toaddrs
    msg['Subject'] = subject
    # Create the body of the message
    html = """\
    <html>
      <head></head>
      <body>
        """+body+"""
      </body>
    </html>
    """
    # Record the MIME types of the parts 
    part1 = MIMEText(html, 'html')
    # Attach parts into message container.
    # According to RFC 2046, the last part of a multipart message, in this case
    # the HTML message, is best and preferred.
    msg.attach(part1)
    # add attachments
    for file in attachmentFiles:       
        part = MIMEBase('application', 'octet-stream')
        part.set_payload(unicode(file.read(), 'utf-8'))
        Encoders.encode_base64(part)
        part.add_header('Content-Disposition', 'attachment', 
               filename=file.name)
        msg.attach(part)        

    # Send the message via local SMTP server.
    username = 'example@gmail.com'
    password = 'examplepwd'
    server = smtplib.SMTP('smtp.gmail.com:587')
    server.starttls()
    server.login(username,password)
    server.sendmail(fromaddr, toaddrs, msg.as_string())
    server.quit()
编辑:我不明白file.read()为什么返回空内容。。。如果有人能解释,那就太好了。无论如何,这里有一个正确的函数,它可以工作:

def sendEmailHtml(fromaddr, toaddrs, body, subject, attachmentFiles=[]):
    """ Sends HTML email using hardcoded server parameters

    attachmentFiles is a list of FileFields
    """
    # Create message container - the correct MIME type is multipart/alternative for alternative
    # formats of the same content. It's related otherwise (e.g., attachments).
    msg = MIMEMultipart('related')
    msg['From'] = fromaddr
    msg['To'] = toaddrs
    msg['Subject'] = subject
    # Create the body of the message (a plain-text and an HTML version).
    # Note: email readers do not support CSS... We have to put everything in line
    html = """\
    <html>
      <head></head>
      <body>
        """+body+"""
      </body>
    </html>
    """
    # Record the MIME types of both parts - text/plain and text/html.
    part1 = MIMEText(html, 'html')
    # Attach parts into message container.
    # According to RFC 2046, the last part of a multipart message, in this case
    # the HTML message, is best and preferred.
    msg.attach(part1)
    # add attachments
    # for debugging
    debug = False
    if debug:
        # force the presence of a single attachment
        if (len(attachmentFiles)!=1):            
            raise NameError("The number of attachments must be exactly 1, not more, not less.")
        else:
            # print the value of every possible way to obtain the content
            content = "[1] "+unicode(attachmentFiles[0].read(), 'utf-8')
            content += "[2] "+attachmentFiles[0].read()
            content += "[3] "+str(attachmentFiles[0])
            content += "[4] "+open(str(attachmentFiles[0]),'r').read()            
            if (len(content)==0):
                raise NameError("The file to be attached is empty !")
            else:
                # print the content
                raise NameError("Everything ok: content="+content)
                pass
    # end of debugging code
    for file in attachmentFiles:
        format, enc = mimetypes.guess_type(file.name)
        main, sub = format.split('/')
        part = MIMEBase(main, sub)       
        #part = MIMEBase('application', 'octet-stream')
        part.set_payload(open(str(file),'r').read())
        #Encoders.encode_base64(part)
        Encoders.encode_quopri(part)
        part.add_header('Content-Disposition', 'attachment', 
               filename=file.name)
        msg.attach(part)        

    # Send the message via local SMTP server.
    username = 'example@gmail.com'
    password = 'thepassword'
    server = smtplib.SMTP('smtp.gmail.com:587')
    server.starttls()
    server.login(username,password)
    server.sendmail(fromaddr, toaddrs, msg.as_string())
    server.quit()
def sendmailhtml(fromaddr,toaddrs,body,subject,attachmentFiles=[]):
“”“使用硬编码的服务器参数发送HTML电子邮件
attachmentFiles是文件字段的列表
"""
#创建消息容器-正确的MIME类型为multipart/alternative for alternative
#相同内容的格式。它在其他方面是相关的(例如,附件)。
msg=MIMEMultipart('相关')
msg['From']=fromaddr
msg['To']=toaddrs
msg['Subject']=主语
#创建消息正文(纯文本和HTML版本)。
#注意:电子邮件阅读器不支持CSS。。。我们必须把一切安排妥当
html=”“”\
“+body+”
"""
#记录这两部分的MIME类型-text/plain和text/html。
part1=MIMEText(html,'html')
#将部件附加到消息容器中。
#根据RFC 2046,在本例中,多部分消息的最后一部分
#HTML消息是最好的首选。
附加信息(第1部分)
#添加附件
#用于调试
调试=错误
如果调试:
#强制存在单个附件
如果(len(附件文件)!=1):
raise NameError(“附件数必须正好为1,不能多,也不能少。”)
其他:
#打印获取内容的所有可能方法的值
content=“[1]”+unicode(附件文件[0]。读取(),'utf-8')
内容+=“[2]”+附件文件[0]。读取()
内容+=“[3]”+str(附件文件[0])
content+=“[4]”+open(str(attachmentFiles[0]),'r')。read()
如果(len(content)==0):
raise NAME错误(“要附加的文件为空!”)
其他:
#打印内容
raise NAME错误(“一切正常:内容=“+content”)
通过
#调试代码结束
对于附件文件中的文件:
格式,enc=mimetypes.guess\u类型(file.name)
main,sub=format.split(“/”)
零件=MIMEBase(主、辅)
#part=MIMEBase('application','octet stream')
part.set_有效载荷(打开(str(文件),'r').read())
#编码器。编码_base64(部分)
编码器。编码器(部分)
部分。添加标题('Content-Disposition'、'attachment',
filename=file.name)
附加信息(部分)
#通过本地SMTP服务器发送邮件。
用户名=example@gmail.com'
密码='thepassword'
server=smtplib.SMTP('SMTP.gmail.com:587')
server.starttls()
server.login(用户名、密码)
sendmail(fromaddr,toaddrs,msg.as\u string())
server.quit()

注意:我忘记了打开后的close指令。

multipart/alternative
用于表示相同内容的多个部分(例如纯文本和HTML,邮件阅读器显示其支持的版本)。如果您改用
multipart/related
,会有帮助吗?谢谢您的提示。我已经更正为multipart/related,但是,我的附件仍然是一个空文件,我已经调试了很多次。unicode(attachmentFiles[0]。read(),'utf-8')是空的attachmentFiles[0]。read()也是空的。str(attachmentFiles[0])包含文件名。因此,我将尝试在不直接读取FileField的情况下打开文件,而是在文件名上使用常用的open命令。
def sendEmailHtml(fromaddr, toaddrs, body, subject, attachmentFiles=[]):
    """ Sends HTML email using hardcoded server parameters

    attachmentFiles is a list of FileFields
    """
    # Create message container - the correct MIME type is multipart/alternative for alternative
    # formats of the same content. It's related otherwise (e.g., attachments).
    msg = MIMEMultipart('related')
    msg['From'] = fromaddr
    msg['To'] = toaddrs
    msg['Subject'] = subject
    # Create the body of the message (a plain-text and an HTML version).
    # Note: email readers do not support CSS... We have to put everything in line
    html = """\
    <html>
      <head></head>
      <body>
        """+body+"""
      </body>
    </html>
    """
    # Record the MIME types of both parts - text/plain and text/html.
    part1 = MIMEText(html, 'html')
    # Attach parts into message container.
    # According to RFC 2046, the last part of a multipart message, in this case
    # the HTML message, is best and preferred.
    msg.attach(part1)
    # add attachments
    # for debugging
    debug = False
    if debug:
        # force the presence of a single attachment
        if (len(attachmentFiles)!=1):            
            raise NameError("The number of attachments must be exactly 1, not more, not less.")
        else:
            # print the value of every possible way to obtain the content
            content = "[1] "+unicode(attachmentFiles[0].read(), 'utf-8')
            content += "[2] "+attachmentFiles[0].read()
            content += "[3] "+str(attachmentFiles[0])
            content += "[4] "+open(str(attachmentFiles[0]),'r').read()            
            if (len(content)==0):
                raise NameError("The file to be attached is empty !")
            else:
                # print the content
                raise NameError("Everything ok: content="+content)
                pass
    # end of debugging code
    for file in attachmentFiles:
        format, enc = mimetypes.guess_type(file.name)
        main, sub = format.split('/')
        part = MIMEBase(main, sub)       
        #part = MIMEBase('application', 'octet-stream')
        part.set_payload(open(str(file),'r').read())
        #Encoders.encode_base64(part)
        Encoders.encode_quopri(part)
        part.add_header('Content-Disposition', 'attachment', 
               filename=file.name)
        msg.attach(part)        

    # Send the message via local SMTP server.
    username = 'example@gmail.com'
    password = 'thepassword'
    server = smtplib.SMTP('smtp.gmail.com:587')
    server.starttls()
    server.login(username,password)
    server.sendmail(fromaddr, toaddrs, msg.as_string())
    server.quit()