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

Django+Whitenoise部署Heroku后上传图片无法访问求助

解决方案:Heroku上Django用户上传图片无法访问的问题

核心问题分析

  1. Heroku临时文件系统限制:Heroku的dyno文件系统是临时存储,用户上传的文件会在dyno重启(部署、自动缩放、故障恢复等场景)后完全丢失,这是平台固有特性,无法直接绕过。
  2. 媒体文件路由生产环境失效:Django的static()辅助函数仅在DEBUG=True时生效,生产环境DEBUG=False时,urls.py中添加的媒体文件路由不会被加载,导致访问返回404。
  3. 静态与媒体目录混淆:你将MEDIA_ROOT放在STATIC_ROOT目录下,Whitenoise仅处理部署时通过collectstatic收集的静态文件,动态上传的媒体文件不会被Whitenoise识别和托管。

修复步骤

1. 分离静态与媒体文件配置

修改settings.py,将媒体文件目录从静态目录中独立出来,避免混淆:

# 保留原静态文件配置
STATIC_URL = '/staticfiles/'
STATIC_ROOT = BASE_DIR / 'staticfiles'
STATICFILES_STORAGE = 'whitenoise.storage.CompressedStaticFilesStorage'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]

# 修改媒体文件配置,使用独立目录
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'

2. 配置生产环境媒体文件路由

在urls.py中手动添加生产环境兼容的媒体文件路由,确保DEBUG=False时也能正常映射:

from django.conf import settings
from django.conf.urls.static import static
from django.views.static import serve

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('accounts.urls')),
]

# 静态文件路由保留
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

# 兼容生产/开发环境的媒体文件路由
if not settings.DEBUG:
    urlpatterns += [
        path(f'{settings.MEDIA_URL.lstrip("/")}<path:path>', serve, {'document_root': settings.MEDIA_ROOT}),
    ]
else:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

3. 使用云存储托管媒体文件(关键解决文件丢失问题)

由于Heroku临时文件系统的限制,必须用云存储服务托管用户上传的媒体文件,推荐使用Cloudinary(配置简单,免费额度满足小型项目需求):

  • 安装依赖:
    pip install django-cloudinary-storage
    
  • 在settings.py中添加Cloudinary配置(注册账号后从控制台获取对应信息):
    INSTALLED_APPS += [
        'cloudinary',
        'cloudinary_storage',
    ]
    
    CLOUDINARY_STORAGE = {
        'CLOUD_NAME': '你的cloud名称',
        'API_KEY': '你的API密钥',
        'API_SECRET': '你的API秘钥',
    }
    
    # 设置默认文件存储为Cloudinary
    DEFAULT_FILE_STORAGE = 'cloudinary_storage.storage.MediaCloudinaryStorage'
    
  • 重新部署到Heroku:
    git add .
    git commit -m "配置Cloudinary托管媒体文件"
    git push heroku main
    

验证

完成配置后,重新通过管理页面或自定义表单上传图片,此时图片会存储在Cloudinary的CDN中,即使Heroku dyno重启,文件也不会丢失,且能正常访问。

内容的提问来源于stack exchange,提问作者Phúc Hoàng

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 19:43:39