Django使用FileField上传文件时如何获取实例按客户ID生成存储路径
问题排查与修复方案
1. 前端表单缺少文件上传必要属性
文件上传表单必须添加enctype="multipart/form-data"属性,否则浏览器不会传输文件内容,导致Django后端request.FILES为空。
修复后的表单代码:
<form method="post" enctype="multipart/form-data"> {% csrf_token %} <input type="file" class="" name="br"> <button type="submit">上传</button> </form>
2. 视图中表单实例化参数顺序错误
自定义的ClientUploadForm的__init__方法第一个参数是path,但实例化时把request.POST作为第一个参数传入,导致参数位置完全错位,request.FILES没有被表单正确接收。
修复视图中的实例化代码:
# 原错误代码:uploadForm = ClientUploadForm(request.POST, request.FILES, instance.customer_id.user_id) # 修正后,把path参数放在第一个位置,后面跟上request.POST和request.FILES uploadForm = ClientUploadForm(instance.customer_id.user_id, request.POST, request.FILES)
3. GET请求下表单实例化错误
当前GET请求时给模板传入的是ClientUploadForm类本身,不是实例化对象,会导致模板渲染异常。修正如下:
# 原错误代码:uploadForm = ClientUploadForm # 修正为实例化对象,传入path参数 uploadForm = ClientUploadForm(instance.customer_id.user_id)
4. 隐藏问题:文件时间戳固定
当前BasicUploadTo的suffix是类变量,只会在服务启动时生成一次,所有上传文件的时间戳都是同一个值。调整为每次调用上传规则时生成:
class BasicUploadTo(): prefix = '' def upload_rules(self, instance, filename): (filename, extension) = os.path.splitext(filename) id = instance.customer_id.customer_id.user_id # 把suffix移到方法内,每次上传生成最新时间戳 suffix = dt.now().strftime("%Y%m%d%H%M%S") return os.path.join(str(id), "Docs", f"{self.prefix}_{suffix}{extension}")
5. 可选优化:表单save方法逻辑优化
当前save方法中先调用commit=True保存,再修改外键后二次保存,可以调整为一次保存减少数据库操作:
def save(self, client_id, commit=True): clientDoc = super(ClientUploadForm, self).save(commit=False) instance = Customer.objects.get(customer_id__user_id=client_id) clientDoc.customer_id = instance if commit: clientDoc.save() return clientDoc
内容的提问来源于stack exchange,提问作者likelitchi
相关产品推荐
相关产品推荐

