如何配置Django对接独立文件服务器实现大文件分发?
Django独立文件服务器配置与集成指南
1. 文件服务器与网站VPS的关联及协议选择
- 子域名+DNS A记录完全可行:把文件服务器的公网IP绑定到
dl.mywebsite.com这类子域名,添加A记录指向该IP即可,用户访问子域名就会直接跳转至文件服务器。 - 协议优先选HTTP/HTTPS:FTP对浏览器支持差,还要额外处理登录验证,用户体验糟糕;HTTP/HTTPS可以直接通过浏览器下载,还能配合Nginx/Apache做限速、防盗链,更适合面向普通用户的场景。大文件下载建议开启HTTP分块传输(Nginx默认支持),提升断点续传体验。
2. Django项目配置文件下载链接
- 无需修改默认的
MEDIA_ROOT和MEDIA_URL(因为文件不在网站VPS本地),直接在产品模型中新增字段存储文件服务器上的文件地址:- 可以用
URLField存储完整下载链接,比如file_url = models.URLField(),值为https://dl.mywebsite.com/files/product1/xxx.zip; - 也可以拆分存储:用
CharField存相对路径(如product1/xxx.zip),在Django配置里加全局常量FILE_SERVER_DOMAIN = "https://dl.mywebsite.com",模板中拼接成完整URL:{{ FILE_SERVER_DOMAIN }}{{ product.file_path }}。
- 可以用
- 核心注意点:必须在视图层判断用户订单状态,仅向已完成支付的用户展示下载链接。
3. 多文件上传与产品关联方案
方案一:Admin直接上传至文件服务器
- 自定义Django文件存储后端:继承
Storage类,实现_save和exists方法,通过SFTP或文件服务器的HTTP上传接口,把Admin上传的文件直接传到独立服务器,模型中存储对应的路径/URL。 - 简化版示例代码:
from django.core.files.storage import Storage import paramiko class SFTPStorage(Storage): def _save(self, name, content): # 连接文件服务器SFTP ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect('dl.mywebsite.com', username='your_user', password='your_pwd') sftp = ssh.open_sftp() # 写入文件到服务器指定目录 with sftp.open(f'/var/www/files/{name}', 'wb') as f: f.write(content.read()) sftp.close() ssh.close() return name # 返回相对路径,后续拼接域名使用 def exists(self, name): # 判断文件是否已存在于服务器 ssh = paramiko.SSHClient() ssh.connect('dl.mywebsite.com', username='your_user', password='your_pwd') sftp = ssh.open_sftp() try: sftp.stat(f'/var/www/files/{name}') return True except FileNotFoundError: return False finally: sftp.close() ssh.close()
- 在模型的
FileField中指定storage=SFTPStorage(),Admin上传时文件会自动同步到文件服务器。
方案二:FTP上传后在Admin关联
- 先通过FTP工具把文件传到文件服务器的固定目录(如
/var/www/files/),然后在Django模型中新增file_path = models.CharField(max_length=255),存储文件的相对路径(如product1/xxx.zip)。 - Admin中直接填写该相对路径,模板里拼接成完整下载URL即可。如果怕手动输入出错,可以自定义Admin字段,调用SFTP获取文件服务器上的文件列表供选择。
4. 文件服务的实现方式
- 如果文件服务器已配置HTTP服务(如Nginx托管静态文件),且做好了防盗链/权限控制(比如仅允许网站VPS的IP访问,或通过签名URL验证),直接用
<a href="文件URL" download>即可,无需Django介入大文件传输,能大幅减轻网站VPS的带宽压力。 - 如果需要更严格的权限控制(比如验证用户购买权限、设置链接有效期),则需要编写自定义视图:
- 视图先验证用户订单状态,通过后生成带签名的临时URL(比如给文件服务器的请求加
时间戳+签名参数,文件服务器的Nginx配合Lua脚本验证签名),或者通过Django做代理返回文件流。但代理大文件会占用网站VPS带宽,优先推荐签名URL方案。
- 视图先验证用户订单状态,通过后生成带签名的临时URL(比如给文件服务器的请求加
内容的提问来源于stack exchange,提问作者Shaw
相关产品推荐
相关产品推荐

