如何在 Django 的 FileField 中保存来自传入电子邮件的附件?

Posted

技术标签:

【中文标题】如何在 Django 的 FileField 中保存来自传入电子邮件的附件?【英文标题】:How to save the attachment from an incoming email in Django's FileField? 【发布时间】:2018-05-20 07:57:07 【问题描述】:

我正在尝试将传入电子邮件的任何附件保存到 Django 中的 FileField。

模型如下所示:

class Email(models.Model):
  ...
  attachment = models.FileField(upload_to='files/%Y/%m/%d', null=True, blank=True)
  ...

  def __unicode__(self):
    return self.contents[:20]

我写了这个函数来返回附件。

def get_attachments(email_object):
    attachments = []
    for part in email_object.walk():
        # content_type = part.get_content_type()
        content_disposition = part.get("Content-Disposition")
        if content_disposition and content_disposition.lower().startswith("attachment"):
            attachments.append(part)
    return attachments

现在我有一个电子邮件对象的实例列表,但我不确定如何将它们保存为 FileField 中的文件。 attachment.get_content_type() 返回image/jpeg。但是我如何从这里开始使它可以保存在文件字段中?

感谢大家的帮助。

【问题讨论】:

【参考方案1】:

要将电子邮件附件保存到目录并保存模型中的记录,您需要执行以下操作,

#firstly change your model design
#an email can have 0 - n attachments

class EmailAttachment(models.Model):
    email = models.ForeignKey(Email)
    document = models.FileField(upload_to='files/%Y/%m/%d')

#if you want to save an attachment
# assume message is multipart
# 'msg' is email.message instance
for part in msg.get_payload():
    if 'attachment' in part.get('Content-Disposition',''):
        attachment = EmailAttachment()
        #saving it in a <uuid>.msg file name
        #use django ContentFile to manage files and BytesIO for stream  
        attachment.document.save(uuid.uuid4().hex + ".msg",
            ContentFile(
                BytesIO(
                    msg.get_payload(decode=True)
                ).getvalue()
            )
        )

【讨论】:

以上是关于如何在 Django 的 FileField 中保存来自传入电子邮件的附件?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Django 中使用 FileField 测试表单?

Django - 如何设置 forms.FileField 名称

Django - 如何创建文件并将其保存到模型的 FileField?

如何将 NamedTemporaryFile 保存到 Django 中的模型 FileField 中?

如何使 django 中的 FileField 成为可选的?

如何在 Django 中使用 HTML 输入类型文件作为 FileField 类型?