如何将Django FileField作为附件发送电子邮件?

Lyl*_*att 6 django email-attachments filefield

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

有人能给我一个如何运作的例子吗?我开始认为在保存文件时我可能必须将Content-Type存储在模型中.

谢谢!

Jer*_*wis 14

在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()
Run Code Online (Sandbox Code Playgroud)


sha*_*k3r 8

我正在使用django-storages,所以.path提高了

NotImplementedError: This backend doesn't support absolute paths.
Run Code Online (Sandbox Code Playgroud)

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

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()
Run Code Online (Sandbox Code Playgroud)


Tom*_*Tom 6

另一种方法:

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))
Run Code Online (Sandbox Code Playgroud)

  • 我不得不在 Django 1.7.1 中使用 `msg.attach_file(self.my_filefield.path)` (2认同)

Jam*_*ury 1

我只是不提供内容类型并让收件人的电子邮件客户端来解决它。除非有什么不寻常的事情,否则应该不成问题。

RFC2616规定:

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

但是...如果您想指定它,那么在上传时存储内容类型是一个非常好的主意。应该注意的是,django自己的文档说要验证用户的数据

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

import subprocess
subprocess.check_output(['file', '-b', '--mime', filename]) 
Run Code Online (Sandbox Code Playgroud)

(来自如何在 python 中查找文件的 mime 类型?