首页 > 解决方案 > 如何在 Django 中将 S3 文件附加到电子邮件

问题描述

我正在尝试将保存在 S3 存储桶中的媒体文件附加到电子邮件中,我正在使用以下代码行:

email.attach_file(standard.download.url)

模型定义如下:

class Standard(models.Model):
    name = models.CharField(max_length = 51)
    download = models.FileField(upload_to="standard_downloads/", null=True, blank=True)

    def __str__(self):
        return self.name

settings.py我定义我的媒体文件如下:

AWS_DEFAULT_ACL = 'public-read'
AWS_S3_CUSTOM_DOMAIN = '%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME
AWS_S3_OBJECT_PARAMETERS = {
    'CacheControl': 'max-age=86400',
}
DEFAULT_FILE_STORAGE = 'sme.storage_backends.MediaStorage'
MEDIA_ROOT = 'https://%s.s3.amazonaws.com/media/' % AWS_STORAGE_BUCKET_NAME

尝试运行我得到的代码时

没有这样的文件或目录:'https:/bucket-name.s3.amazonaws.com/media/standard_downloads/filename.ext

请注意,它显示为https:/(单个 /)。我该如何纠正?

标签: pythondjangoamazon-s3boto3

解决方案


attach_file这是来自 Django的源代码。它清楚地表明 - 从文件系统附加文件。它不适用于远程 URL。当你给它一个 url 时,它认为你指的是本地文件,所以它将所有双斜杠转义为单斜杠。

def attach_file(self, path, mimetype=None):
    """
    Attach a file from the filesystem.

    Set the mimetype to DEFAULT_ATTACHMENT_MIME_TYPE if it isn't specified
    and cannot be guessed.

    For a text/* mimetype (guessed or specified), decode the file's content
    as UTF-8. If that fails, set the mimetype to
    DEFAULT_ATTACHMENT_MIME_TYPE and don't decode the content.
    """
    path = Path(path)
    with path.open('rb') as file:
        content = file.read()
        self.attach(path.name, content, mimetype)

Django 没有为此提供任何内置功能。您将不得不在上面的代码行上编写一些自定义的东西,也可以使用像requestor之类的库boto。基本上这个想法是从远程 url 获取保存为 temp 然后使用attach它。

这是一个关于如何即时获取文件的示例:

from django.core.mail.message import attach
import requests
response = requests.get("http://yoururl/somefile.pdf")
email.attach('My file',response.read(),mimetype="application/pdf")

推荐阅读