如何在Django中生成可下载CSV的同时将其保存到media文件夹
实现方案
你只需要在原有生成CSV供下载的逻辑基础上,额外将写入HttpResponse的内容同步写入到MEDIA目录下的本地文件即可,以下是修改后的完整代码:
首先导入依赖模块:
import os import csv from django.conf import settings from django.http import HttpResponse from .models import Industry
修改后的视图函数:
def to_csv(request): # 初始化下载用的HttpResponse response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename=industry.csv' response_writer = csv.writer(response) # 构造MEDIA目录下的CSV文件保存路径,初始化本地文件写入器 local_csv_path = os.path.join(settings.MEDIA_ROOT, 'industry.csv') # 用with上下文管理器自动处理文件关闭,避免资源泄漏 with open(local_csv_path, 'w', newline='', encoding='utf-8') as f: local_writer = csv.writer(f) # 写入表头,同时写给下载响应和本地文件 header = ['Name','Workplace and Designation','Contact No.','Email ID','Purpose of Visit','Self Employed Details'] response_writer.writerow(header) local_writer.writerow(header) # 逐行写入数据,同时写给两个写入器 data = Industry.objects.all() for row in data: row_data = [row.name, row.wp_des, row.mobileno, row.email, row.purpose, row.semp_details] response_writer.writerow(row_data) local_writer.writerow(row_data) return response
注意事项
- 确保运行Django服务的系统用户对
MEDIA_ROOT配置的目录有读写权限,否则会出现文件写入失败的报错 - 如果你需要保留历史导出的CSV文件不被覆盖,可以给文件名增加时间戳、UUID等唯一标识后缀,示例如下:
import time # 生成带时间戳的文件名,避免覆盖 file_name = f"industry_{int(time.time())}.csv" local_csv_path = os.path.join(settings.MEDIA_ROOT, file_name) # 同时修改下载响应的文件名 response['Content-Disposition'] = f'attachment; filename={file_name}' - 如果CSV导出数据量极大,可优化为使用生成器逐行写入,避免占用过多服务器内存
内容的提问来源于stack exchange,提问作者Kunal Kamble
相关产品推荐
相关产品推荐

