如何将模板和静态文件上传到Django应用并修正默认存储路径
问题原因
Django 默认所有 FileField/ImageField 都会使用全局配置的默认文件存储方案,存储根路径对应 settings.py 里定义的 MEDIA_ROOT,所以你设置的 upload_to 路径都会拼在 MEDIA_ROOT 之后,导致所有文件都存入全局 media 目录。
调整方案
你可以为需要存到应用目录的文件字段自定义独立的文件存储实例,修改你的模型代码如下:
import os from django.conf import settings from django.db import models from django.utils.timezone import now from django.core.files.storage import FileSystemStorage # 自定义模板文件存储:根路径指向projects应用的templates/projects目录 project_template_storage = FileSystemStorage( location=os.path.join(settings.BASE_DIR, 'projects', 'templates', 'projects'), base_url='/templates/projects/' ) # 自定义静态资源存储:根路径指向projects应用的static/projects目录 project_static_storage = FileSystemStorage( location=os.path.join(settings.BASE_DIR, 'projects', 'static', 'projects'), base_url='/static/projects/' ) class Project(models.Model): class ProjectType(models.TextChoices): PYTHON = 'Python' JAVASCRIPT = 'Javascript' REACTJS = 'React.js' REACTNATIVE = 'React Native' JAVA = 'Java' C = 'C' CPP = 'C++' def upload_location_photo(instance, filename): return f'photos/projects/{instance.slug}/{filename}' # 调整上传路径:存储根路径已经定位到对应目录,只需要返回slug+文件名即可,避免路径重复 def upload_location_template(instance, filename): return f'{instance.slug}/{filename}' def upload_location_static(instance, filename): return f'{instance.slug}/{filename}' slug = models.CharField(max_length=200, unique=True) project_type = models.CharField(max_length=50, choices=ProjectType.choices, default=ProjectType.JAVASCRIPT) title = models.CharField(max_length=150) description = models.TextField(blank=True) date_completed = models.DateTimeField(default=now, blank=True) photo_main = models.ImageField(upload_to=upload_location_photo) photo_1 = models.ImageField(upload_to=upload_location_photo, blank=True) photo_2 = models.ImageField(upload_to=upload_location_photo, blank=True) photo_3 = models.ImageField(upload_to=upload_location_photo, blank=True) # 给对应文件字段添加自定义storage参数 file_html = models.FileField(upload_to=upload_location_template, storage=project_template_storage, max_length=100, blank=True) file_css = models.FileField(upload_to=upload_location_static, storage=project_static_storage, max_length=100, blank=True) file_js = models.FileField(upload_to=upload_location_static, storage=project_static_storage, max_length=100, blank=True)
注意事项
- 请确保
projects/templates/projects和projects/static/projects两个目录存在,且运行Django服务的系统用户对这两个目录有读写权限 - 该方案仅适合个人小型项目使用,生产环境不建议将用户上传的动态文件存入应用的static、templates目录:一来不符合Django的目录设计规范,二来执行
collectstatic命令时可能会出现文件覆盖冲突,生产环境建议仍将动态文件存在media目录,通过自定义视图实现访问渲染逻辑
内容的提问来源于stack exchange,提问作者Micheal Nestor
相关产品推荐
相关产品推荐

