You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过S3 URL在Django Emailer中附加文档且无需下载至服务器

当然可以做到!不用把S3上的文件下载到服务器就能直接附加到Django邮件里,还不会暴露你的S3 URL,我给你详细说下怎么实现:

核心思路

Django的EmailMessage类支持直接将内存中的文件内容作为附件添加,不需要先保存到本地服务器。我们只需要从S3直接读取文件的二进制内容,再传给邮件的attach()方法即可。

具体实现方案

方案一:使用boto3直接操作S3

如果你直接用boto3来访问S3,可以这样写:

首先安装兼容Python2.7的boto3版本(最后支持Python2.7的是1.18.x版本):

pip install boto3==1.18.69

然后编写代码:

import boto3
from django.core.mail import EmailMessage
from botocore.exceptions import ClientError

def get_s3_file_content(bucket_name, s3_file_key):
    """从S3读取文件内容和MIME类型"""
    s3_client = boto3.client('s3')
    try:
        response = s3_client.get_object(Bucket=bucket_name, Key=s3_file_key)
        # 读取文件二进制内容,获取MIME类型
        file_content = response['Body'].read()
        mime_type = response['ContentType']
        return file_content, mime_type
    except ClientError as e:
        print(f"读取S3文件出错: {e}")
        return None, None

# 发送邮件的逻辑
def send_email_with_s3_attachments():
    # 替换成你的S3桶名和文件路径
    s3_bucket = "your-s3-bucket-name"
    pdf_s3_key = "path/to/your/document.pdf"
    image_s3_key = "path/to/your/image.jpg"

    # 获取文件内容和MIME类型
    pdf_content, pdf_mime = get_s3_file_content(s3_bucket, pdf_s3_key)
    image_content, image_mime = get_s3_file_content(s3_bucket, image_s3_key)

    if not (pdf_content and image_content):
        print("无法获取S3文件内容,终止发送")
        return

    # 创建邮件对象
    email = EmailMessage(
        subject="带S3附件的邮件",
        body="这是包含S3文件附件的测试邮件",
        from_email="sender@example.com",
        to=["recipient@example.com"]
    )

    # 添加附件:参数是(显示的文件名, 文件二进制内容, MIME类型)
    email.attach("report.pdf", pdf_content, pdf_mime)
    email.attach("header.jpg", image_content, image_mime)

    # 发送邮件
    email.send(fail_silently=False)

方案二:使用django-storages(如果你已经在用这个库)

如果你的Django项目已经配置了django-storages来管理S3存储,代码会更简洁:

from django.core.files.storage import default_storage
from django.core.mail import EmailMessage

def send_email_with_s3_attachments():
    # 替换成你的存储中的文件路径
    pdf_file_path = "documents/report.pdf"
    image_file_path = "images/banner.png"

    # 从存储中读取文件内容
    with default_storage.open(pdf_file_path, 'rb') as pdf_file:
        pdf_content = pdf_file.read()
        pdf_mime = default_storage.get_content_type(pdf_file_path)
    
    with default_storage.open(image_file_path, 'rb') as image_file:
        image_content = image_file.read()
        image_mime = default_storage.get_content_type(image_file_path)

    # 创建并发送邮件
    email = EmailMessage(
        subject="带S3附件的邮件",
        body="邮件内容",
        from_email="sender@example.com",
        to=["recipient@example.com"]
    )

    email.attach("report.pdf", pdf_content, pdf_mime)
    email.attach("banner.png", image_content, image_mime)
    email.send(fail_silently=False)
注意事项
  • 确保你的Django环境已经配置好S3访问权限:在settings.py中设置AWS_ACCESS_KEY_ID和AWS_SECRET_ACCESS_KEY,或者通过IAM角色赋予服务器访问S3的权限。
  • 对于超大文件,直接读取到内存可能会占用过多资源,但邮件服务本身通常会限制附件大小(比如多数服务商限制25MB以内),所以一般场景下没问题。
  • Python2.7和Django1.9都支持上述代码,不需要额外升级依赖。

内容的提问来源于stack exchange,提问作者nimeshkiranverma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:41:30