Django/DRF中如何按员工ID将媒体文件上传到对应专属文件夹
Django 实现上传文件自动存入员工ID对应专属文件夹
Django 内置的文件存储逻辑会自动递归创建upload_to返回路径中不存在的目录,不需要手动编写文件夹创建代码,核心是给FileField的upload_to传入动态路径生成函数,具体实现如下:
1. 定义动态路径生成函数
直接在models.py中添加路径生成方法,函数接收两个固定参数:当前附件模型实例、上传文件的原始文件名,返回相对于MEDIA_ROOT的存储路径:
import os from django.db import models def get_employee_cv_path(instance, filename): # 获取关联员工的唯一ID emp_id = instance.employee.id_number # 提取原始文件后缀,统一用员工ID作为文件名,匹配要求的emp001.pdf格式 file_ext = os.path.splitext(filename)[1] final_filename = f"{emp_id}{file_ext}" # 拼接最终存储路径 return f"employee/attachments/{emp_id}/{final_filename}"
如果你不需要重命名文件,要保留用户上传的原始文件名,直接把
final_filename替换为传入的filename即可。
2. 修改附件模型字段配置
将EmployeeAttachments模型中cv字段的upload_to参数替换为上面定义的函数,注意不要加括号调用函数,直接传函数对象本身:
class Employee(models.Model): id_number = models.CharField(primary_key=True, null=False, blank=False, unique=True, max_length=15) full_name = models.CharField(max_length=255, null=False, blank=False) name_with_initials = models.CharField(max_length=255, null=False, blank=False) surname = models.CharField(max_length=255, null=False, blank=False) phone = models.CharField(max_length=15, null=False, blank=False) dob = models.DateField(null=False, blank=False) gender = models.CharField(max_length=10, null=False, blank=False) email = models.EmailField() address = models.CharField(max_length=255, null=False, blank=False) class EmployeeAttachments(models.Model): employee = models.ForeignKey(Employee, on_delete=models.CASCADE) cv = models.FileField(upload_to=get_employee_cv_path, max_length=100)
3. DRF 接口配置说明
使用django-rest-framework时不需要额外编写文件存储逻辑,直接用ModelSerializer序列化附件模型即可:
from rest_framework import serializers from .models import EmployeeAttachments class EmployeeAttachmentSerializer(serializers.ModelSerializer): class Meta: model = EmployeeAttachments fields = "__all__"
- 注意事项:创建
EmployeeAttachments实例时,必须先绑定关联的employee对象(或传递合法的员工主键),否则路径生成函数无法获取员工ID会抛出异常。如果业务上存在先传文件再绑定员工的场景,需要调整存储逻辑,在绑定员工后再移动文件到对应目录。
效果验证
配置完成后,为ID为emp001的员工上传PDF格式的CV时,文件会自动存储到MEDIA_ROOT/employee/attachments/emp001/emp001.pdf路径,完全匹配要求的目录结构,中间不存在的层级目录Django会自动创建。
内容的提问来源于stack exchange,提问作者Sandun Tharaka
相关产品推荐
相关产品推荐

