Django2.0.6部署GCE Apache:媒体文件存储路径错误及生产环境配置咨询
一、先修复媒体文件上传路径错误(存到MEDIA_DIR而非MEDIA_ROOT)
首先,你的配置里同时定义了MEDIA_DIR和MEDIA_ROOT,但上传文件时指向了MEDIA_DIR,大概率是代码里的保存逻辑没正确使用MEDIA_ROOT。你需要做以下检查:
检查模型字段配置:确保你的
FileField或ImageField的upload_to参数是相对路径,Django会自动将其拼接在MEDIA_ROOT之后。比如:# 正确示例 class MyModel(models.Model): upload_file = models.FileField(upload_to='uploads/') # 最终保存到MEDIA_ROOT/uploads/避免直接在
upload_to里硬编码MEDIA_DIR的绝对路径,否则会绕过MEDIA_ROOT的配置。检查自定义文件保存逻辑:如果是通过视图手动保存文件,确保使用
settings.MEDIA_ROOT作为根路径,比如:from django.conf import settings import os def save_file(request): if request.FILES.get('my_file'): file = request.FILES['my_file'] save_path = os.path.join(settings.MEDIA_ROOT, 'uploads', file.name) with open(save_path, 'wb+') as destination: for chunk in file.chunks(): destination.write(chunk)清理冗余配置:
MEDIA_DIR这个配置在生产环境其实没必要保留,建议统一用MEDIA_ROOT作为媒体文件的根目录,避免混淆。
二、配置Apache正确服务媒体文件(生产环境)
生产环境绝对不能依赖Django的static()视图来服务媒体文件,必须让Apache直接处理,步骤如下:
1. 确认目录权限
首先确保/var/www/media-root和/var/www/venv/src/media(你的MEDIA_DIR)的权限正确,Apache进程(通常是www-data用户)需要有读写权限:
# 设置所有者为www-data sudo chown -R www-data:www-data /var/www/media-root /var/www/venv/src/media # 设置权限 sudo chmod -R 755 /var/www/media-root /var/www/venv/src/media
2. 修改Apache配置文件
找到你的Django站点的Apache配置(通常在/etc/apache2/sites-available/下),添加两个Alias指令,分别映射MEDIA_URL到MEDIA_ROOT,以及你需要服务的MEDIA_DIR(如果必须保留的话):
# 映射MEDIA_URL到MEDIA_ROOT Alias /media/ /var/www/media-root/ <Directory /var/www/media-root/> Require all granted Options Indexes FollowSymLinks </Directory> # 如果需要服务原MEDIA_DIR的文件,添加额外Alias(比如用/media-local/路径访问) Alias /media-local/ /var/www/venv/src/media/ <Directory /var/www/venv/src/media/> Require all granted Options Indexes FollowSymLinks </Directory> # 保留你现有的WSGI配置 WSGIDaemonProcess django_app python-home=/var/www/venv python-path=/var/www/venv/src WSGIProcessGroup django_app WSGIScriptAlias / /var/www/venv/src/myproject/wsgi.py <Directory /var/www/venv/src/myproject> <Files wsgi.py> Require all granted </Files> </Directory>
3. 重启Apache生效
sudo systemctl restart apache2
三、优化环境配置(区分生产/本地)
你目前没有区分生产和本地的配置,建议调整配置结构,避免混淆:
在
settings目录下创建prod.py,继承base.py,覆盖生产环境专属配置:# settings/prod.py from .base import * # 生产环境禁用DEBUG DEBUG = False ALLOWED_HOSTS = ['你的域名或GCE实例IP'] # 确认生产环境MEDIA_ROOT配置 MEDIA_ROOT = os.path.join(os.path.dirname(os.path.dirname(BASE_DIR)), "media-root")本地开发用
local.py,同样继承base.py,设置本地专属配置:# settings/local.py from .base import * DEBUG = True ALLOWED_HOSTS = ['localhost', '127.0.0.1'] # 本地可以用MEDIA_DIR作为根目录(如果需要) MEDIA_ROOT = MEDIA_DIR通过环境变量指定生产环境使用
prod.py:
在Apache的WSGI配置里添加环境变量:WSGIDaemonProcess django_app python-home=/var/www/venv python-path=/var/www/venv/src WSGIProcessGroup django_app WSGIScriptAlias / /var/www/venv/src/myproject/wsgi.py # 添加这行指定生产环境配置 SetEnv DJANGO_SETTINGS_MODULE myproject.settings.prod
内容的提问来源于stack exchange,提问作者Niladry Kar

