Django实现用户上传CSV文件至服务器指定目录
嘿,我来帮你梳理Django实现CSV文件上传到指定文件夹的具体步骤,一步步来很容易搞定:
实现CSV文件上传到指定文件夹的完整流程
1. 先搞定上传路径与权限配置
首先在你的项目目录下创建目标文件夹,比如uploads/csv_files(可以自定义路径)。一定要确保服务器进程(比如Django的runserver、uWSGI)对这个文件夹有读写权限,不然上传时会直接报PermissionError——我自己踩过这个坑,提前用chmod 755 uploads/csv_files(Linux环境)或者手动设置Windows权限准没错。
然后在settings.py里添加自定义的上传路径配置,方便后续调用:
import os from pathlib import Path BASE_DIR = Path(__file__).resolve().parent.parent # 自定义CSV上传根目录 CSV_UPLOAD_ROOT = os.path.join(BASE_DIR, 'uploads', 'csv_files')
2. 编写文件上传表单(带验证)
创建forms.py,用Django的FileField来处理文件上传,同时添加验证规则,防止用户传错文件:
from django import forms class CSVUploadForm(forms.Form): csv_file = forms.FileField( label='选择CSV文件', widget=forms.ClearableFileInput(attrs={'class': 'form-control'}) ) # 验证文件格式必须是CSV def clean_csv_file(self): uploaded_file = self.cleaned_data.get('csv_file') if not uploaded_file.name.lower().endswith('.csv'): raise forms.ValidationError('请上传后缀为.csv的文件!') # 可选:限制文件大小(比如5MB) if uploaded_file.size > 5 * 1024 * 1024: raise forms.ValidationError('文件大小不能超过5MB!') return uploaded_file
3. 编写处理上传的视图函数
在views.py里写视图,处理POST请求时接收文件,然后保存到你指定的文件夹:
import os from django.shortcuts import render, redirect from django.conf import settings from django.contrib import messages from .forms import CSVUploadForm def upload_csv(request): if request.method == 'POST': form = CSVUploadForm(request.POST, request.FILES) if form.is_valid(): csv_file = form.cleaned_data['csv_file'] # 处理文件名:避免重名可以加时间戳或UUID # 示例:用时间戳前缀重命名 import datetime timestamp = datetime.datetime.now().strftime('%Y%m%d%H%M%S') safe_filename = f"{timestamp}_{csv_file.name}" # 构造完整保存路径 save_path = os.path.join(settings.CSV_UPLOAD_ROOT, safe_filename) # 分块写入文件(处理大文件时避免内存溢出) with open(save_path, 'wb+') as destination: for chunk in csv_file.chunks(): destination.write(chunk) # 给用户返回成功提示 messages.success(request, 'CSV文件上传成功!') return redirect('upload_csv') # 重定向回上传页面 else: form = CSVUploadForm() return render(request, 'upload_csv.html', {'form': form})
这里用chunks()分块写入是个好习惯,尤其是处理大CSV文件时,不会一次性把文件加载到内存里。
4. 创建上传页面模板
在templates目录下创建upload_csv.html,注意表单必须加enctype="multipart/form-data",否则文件根本传不上去:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>上传CSV文件</title> </head> <body> <h2>CSV文件上传</h2> <!-- 显示成功/错误提示 --> {% if messages %} {% for msg in messages %} <div style="color: green; margin: 10px 0;">{{ msg }}</div> {% endfor %} {% endif %} <!-- 上传表单:必须加enctype属性 --> <form method="post" enctype="multipart/form-data"> {% csrf_token %} {{ form.as_p }} <button type="submit" style="padding: 8px 16px;">确认上传</button> </form> </body> </html>
5. 配置URL路由
在项目的urls.py(或者app的urls.py)里添加路由:
from django.urls import path from . import views urlpatterns = [ # 其他路由... path('upload-csv/', views.upload_csv, name='upload_csv'), ]
额外的实用提示
- 文件重名问题:除了时间戳,你也可以用
uuid生成唯一文件名,比如import uuid; safe_filename = f"{uuid.uuid4()}_{csv_file.name}",彻底避免重名覆盖。 - 安全风险:不要把上传文件夹配置到Web可直接访问的目录下(比如
static文件夹),防止恶意文件被执行;如果之后要解析CSV,一定要做好数据清洗,避免注入风险。 - 大文件支持:如果要上传超过10MB的CSV,需要在
settings.py里调整FILE_UPLOAD_MAX_MEMORY_SIZE,或者用第三方库实现分块上传。
内容的提问来源于stack exchange,提问作者saum
相关产品推荐
相关产品推荐

