【问题标题】:How to Email a Django FileField as an Attachment?如何通过电子邮件将 Django FileField 作为附件发送?
【发布时间】:2011-09-23 22:42:13
【问题描述】:

我需要使用 Django 将models.FileField 作为电子邮件附件发送。我已经看到 sn-ps 显示如何使用原始 request.FILES 数据(仍包含 Content-Type)执行此操作,但是一旦您已经保存,就无法找到任何显示如何执行此操作的内容models.FileField 中的文件。内容类型似乎无法从 models.FileField 访问。

谁能给我一个例子来说明它是如何工作的?我开始认为我可能必须在保存文件时将 Content-Type 存储在模型中。

谢谢!

【问题讨论】:

  • 您能否提供您找到的解决方案作为答案?我也想看sn-p。

标签: django email-attachments filefield


【解决方案1】:

我不会提供内容类型,而是让收件人的电子邮件客户端来解决。除非它是不寻常的东西,否则它不应该是一个问题。

RFC2616 状态:

当且仅当媒体类型不是 由 Content-Type 字段给出, 收件人可以尝试猜测 媒体类型通过检查其 内容和/或扩展名 用于标识的 URI 资源。

但是... 如果您想指定它,那么在上传时存储内容类型是一个非常好的主意。需要注意的是,django 自己的文档说给verify the data from users

如果您使用的是 *unix 操作系统,您可以尝试猜测/检查它:

import subprocess
subprocess.check_output(['file', '-b', '--mime', filename]) 

(来自How to find the mime type of a file in python?

【讨论】:

  • 谢谢!我会试一试并报告!
【解决方案2】:

在 Django 中将 models.FileField 文件附加到电子邮件中既简单又方便:

from django.core.mail import EmailMultiAlternatives
kwargs = dict(
    to=to,
    from_email=from_addr,
    subject=subject,
    body=text_content,
    alternatives=((html_content, 'text/html'),)
)
message = EmailMultiAlternatives(**kwargs)
message.attach_file(model_instance.filefield.path)
message.send()

【讨论】:

    【解决方案3】:

    另一种方法:

    from django.core.mail.message import EmailMessage
    
    msg = EmailMessage(subject=my_subject, body=my_email_body, 
          from_email=settings.DEFAULT_FROM_EMAIL, to=[to_addressed])
    msg.attach_file(self.my_filefield.path) # self.my_filefield.file for Django < 1.7
    msg.send(fail_silently=not(settings.DEBUG))
    

    【讨论】:

    • 我不得不在 Django 1.7.1 中使用 msg.attach_file(self.my_filefield.path)
    【解决方案4】:

    我正在使用django-storages.path 加注

    NotImplementedError: This backend doesn't support absolute paths.
    

    为了避免这种情况,我只是打开文件,阅读它,猜测 mimetype 并稍后关闭它,但必须使用 .attach 而不是 .attach_file 魔法。

    from mimetypes import guess_type
    from os.path import basename
    
    
    f = model.filefield
    f.open()
    # msg.attach(filename, content, mimetype)
    msg.attach(basename(f.name), f.read(), guess_type(f.name)[0])
    f.close()
    

    【讨论】:

    • django 邮件模块没有为存储后端提供更好的接口似乎很奇怪。这是使用多个后端的最安全的答案,如果您不使用文件系统后端,这也是您需要的答案。提出的问题是如何通过电子邮件将 django 文件字段作为附件发送,但取决于文件系统存储上的文件的答案实际上只是回答了该文件系统存储后端配置的问题。
    猜你喜欢
    • 1970-01-01
    • 2014-01-10
    • 2021-07-18
    • 2023-03-23
    • 1970-01-01
    • 2021-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多