Django中如何将生成的CSV文件附加到邮件中?
将生成的CSV文件附加到邮件中的解决方案
核心思路
你当前的export_to_csv函数返回的是HttpResponse对象,其中已经包含了CSV的完整内容。要将它作为邮件附件,只需提取该对象中的CSV内容,再通过Django的邮件工具添加附件即可。
方案一:直接利用现有export_to_csv函数
无需修改现有函数,直接从返回的HttpResponse中提取内容构建邮件:
from django.core.mail import EmailMessage from django.http import HttpResponse def get(self, request, *args, **kwargs): serializer = self.get_serializer(self.get_queryset(), many=True) file_format = request.query_params.get("file_format", "csv") if file_format == "csv": # 获取生成CSV的HttpResponse csv_response = export_to_csv( serializer.data, list(self.get_serializer().Meta.fields), "students" ) # 提取CSV二进制内容 csv_content = csv_response.content # 定义附件文件名 file_name = "students.csv" # 构建邮件 email = EmailMessage( '学生数据CSV文件', '附件为您需要的学生数据', '发送邮箱@example.com', ['接收邮箱@example.com'], ) # 添加CSV附件,指定文件名和MIME类型 email.attach(file_name, csv_content, 'text/csv') # 发送邮件 email.send() return HttpResponse("CSV文件已通过邮件发送", status=200)
方案二:重构export_to_csv函数提升灵活性
如果需要同时支持下载CSV和邮件附件两种场景,可以重构函数,让它返回CSV内容和文件名,而非直接返回HttpResponse:
import csv from io import StringIO from django.utils.translation import gettext as _ def export_to_csv(data, titles, file_name): # 在内存缓冲区生成CSV内容 output = StringIO() writer = csv.DictWriter( output, fieldnames=titles, extrasaction="ignore", ) # 生成翻译后的表头 headers = {title: _(title).replace("_", " ").title() for title in titles} writer.writerow(headers) # 写入数据行 for row in data: writer.writerow(row) # 获取UTF-8编码的CSV内容 csv_content = output.getvalue().encode('utf-8') output.close() return csv_content, f"{file_name}.csv"
然后在视图中根据需求选择使用:
def get(self, request, *args, **kwargs): serializer = self.get_serializer(self.get_queryset(), many=True) file_format = request.query_params.get("file_format", "csv") if file_format == "csv": csv_content, file_name = export_to_csv( serializer.data, list(self.get_serializer().Meta.fields), "students" ) # 场景1:发送邮件附件 email = EmailMessage( '学生数据CSV文件', '附件为您需要的学生数据', '发送邮箱@example.com', ['接收邮箱@example.com'], ) email.attach(file_name, csv_content, 'text/csv') email.send() # 场景2:返回下载响应(保留原功能) # response = HttpResponse(content_type="text/csv") # response["Content-Disposition"] = f"attachment; filename={file_name}" # response.write(csv_content) # return response return HttpResponse("CSV文件已通过邮件发送", status=200)
注意事项
- 确保在Django的
settings.py中正确配置邮件参数(如EMAIL_BACKEND、EMAIL_HOST、EMAIL_PORT等) - 若CSV包含中文,需确保使用UTF-8编码,避免出现乱码问题
- 可根据实际需求调整邮件的主题、正文、收件人列表等参数
内容的提问来源于stack exchange,提问作者Montio5
相关产品推荐
相关产品推荐

