You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django 2如何将上传文件存储到项目目录之外?

嘿,我来帮你搞定把Django课程banner存到项目目录外的需求~ 结合你的Django 2版本和现有代码,给你两种可行的方案,按需选择:

方案一:仅针对Course的banner字段单独存储(推荐)

这种方式不会影响其他模型的上传字段,灵活性更高。

步骤1:在local.py中定义外部存储目录并创建自定义存储类

打开你的app/settings/local.py,在BASE_DIR定义后添加以下代码:

import os
from django.core.files.storage import FileSystemStorage

BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

# 定义项目外的存储目录,比如项目父目录下的course_banners文件夹
# 你可以改成任意绝对路径,比如 '/var/www/course_banners'
EXTERNAL_COURSE_BANNER_DIR = os.path.join(os.path.dirname(BASE_DIR), 'course_banners')
# 自动创建目录,避免上传时因目录不存在报错
os.makedirs(EXTERNAL_COURSE_BANNER_DIR, exist_ok=True)

# 自定义存储类,指定外部目录
class ExternalCourseBannerStorage(FileSystemStorage):
    def __init__(self, location=EXTERNAL_COURSE_BANNER_DIR, base_url=None):
        super().__init__(location, base_url)

步骤2:修改Course模型的banner字段

在你的models.py中,引入刚才定义的存储类,并给banner字段指定storage参数:

from django.db import models
import uuid
from app.settings.local import ExternalCourseBannerStorage

class Course(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(max_length=250)
    banner = models.ImageField(
        upload_to='%Y/%m/%d',  # 这是外部目录下的子路径,保持原有的按日期归档逻辑
        blank=True,
        storage=ExternalCourseBannerStorage()
    )

步骤3:配置访问路由(可选,用于前端显示图片)

如果需要在前端展示banner图片,需要给外部存储的文件配置访问路由。打开项目的urls.py,添加:

from django.urls import path
from django.views.static import serve
from app.settings.local import EXTERNAL_COURSE_BANNER_DIR

urlpatterns = [
    # 你的其他路由...
    path('course-banners/<path:path>', serve, {
        'document_root': EXTERNAL_COURSE_BANNER_DIR,
    }),
]

然后可以在Course模型里加一个方法快速获取图片URL:

class Course(models.Model):
    # ... 已有字段
    def get_banner_url(self):
        if self.banner:
            return f'/course-banners/{self.banner.name}'
        return ''

方案二:全局修改所有上传文件的存储位置

如果希望所有FileField/ImageField的文件都存到项目外,直接修改MEDIA_ROOT即可:

# app/settings/local.py
MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), 'external_media')
MEDIA_URL = '/media/'

这种情况下你的Course模型不需要修改,原有的upload_to='course/%Y/%m/%d'会自动将文件存在项目父目录/external_media/course/年/月/日/路径下。

注意事项

  • 确保运行Django的用户(比如本地开发的你的账号,生产环境的www-data)对外部存储目录有读写权限,否则会上传失败。
  • 生产环境中,建议用Nginx/Apache直接代理外部存储目录的访问,性能比Django的serve视图更好。

内容的提问来源于stack exchange,提问作者Anuj TBE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:39:29