Wagtail CMS文档返回404错误求助:S3存储文档无法访问
排查Wagtail + S3文档上传后404的问题
我之前碰到过类似的S3+Wagtail多服务器部署问题,结合你的场景,这几个方向可以逐一排查:
1. 核对S3存储路径与Wagtail生成的URL是否匹配
首先登录S3控制台找到你上传的文档,复制它的实际存储路径(比如media/documents/2024/05/report.pdf),然后和模板里{{ item.url }}输出的URL做对比。
- Wagtail默认的文档存储路径是
documents/YYYY/MM/文件名,但如果你的AWS_LOCATION或者Wagtail的DOCUMENTS_ROOT做了自定义配置,就可能出现路径不匹配的情况。比如如果AWS_LOCATION设为static,媒体文件会被存在static/documents/...,但Wagtail还是生成media/documents/...的URL,直接导致404。
2. 检查Django Storages的媒体存储配置
确保你的settings.py里的媒体相关配置没有混淆静态和媒体文件的存储路径:
# 基础媒体配置 MEDIA_URL = '/media/' DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage' AWS_STORAGE_BUCKET_NAME = '你的桶名' AWS_S3_REGION_NAME = '你的区域' # 比如ap-southeast-1 AWS_S3_FILE_OVERWRITE = False AWS_DEFAULT_ACL = 'public-read' # 如果文档需要公开访问的话 # 更稳妥的方式:给媒体文件单独配置存储类,避免和静态文件冲突 class MediaStorage(S3Boto3Storage): location = 'media' file_overwrite = False DEFAULT_FILE_STORAGE = '你的项目名.storage.MediaStorage'
这个配置会把所有媒体文件(包括Wagtail的文档)存在S3的media/前缀下,和静态文件彻底分开,避免路径混乱。
3. 排查负载均衡环境的配置一致性
因为你用了两台服务器,一定要确认两台机器的Django配置完全一致:
- 检查两台服务器的
AWS_*环境变量或者settings参数,有没有某一台写错了S3桶名、区域或者存储路径? - 尝试重启两台服务器上的Wagtail服务,避免旧的缓存配置导致路径错误。
4. 验证S3对象的权限与访问权限
虽然上传成功了,但还是要确认:
- 上传的文档ACL是否设置为
public-read(如果你的站点需要公开访问文档); - 服务器使用的IAM角色/用户是否拥有S3对象的
HeadObject和GetObject权限——如果是权限问题,错误提示会是AccessDenied,但偶尔也会因为权限不足返回404,这点可以排除一下。
5. 检查自定义文档模型的URL逻辑
如果你自定义了Wagtail的Document模型,要确认没有重写url或者get_url属性导致路径错误:
from wagtail.documents.models import AbstractDocument class CustomDocument(AbstractDocument): # 如果你重写了get_url,确保逻辑是继承父类的正确逻辑 def get_url(self, request=None): return super().get_url(request)
快速调试小技巧
可以在Django Shell里手动打印文档的URL,直接对比S3实际路径:
python manage.py shell from wagtail.documents.models import Document doc = Document.objects.first() print(doc.url)
内容的提问来源于stack exchange,提问作者hammygoonan
相关产品推荐
相关产品推荐

