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

如何用Django Rest Framework实现媒体目录读写与文件链接返回?

使用Django Rest Framework实现Media目录的读写与文件列表接口

刚好做过类似的需求,我来一步步帮你实现想要的功能——允许用户读写media目录,同时GET请求返回指定格式的文件链接列表。

一、先配置Media目录的基础设置

首先得让Django正确识别你的media目录,在项目的settings.py里添加以下配置:

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

# 配置Media目录路径(对应你的myproject/media结构)
MEDIA_ROOT = os.path.join(BASE_DIR, 'myproject', 'media')
# 配置Media访问的URL前缀
MEDIA_URL = '/media/'

然后在项目根目录的urls.py里添加media文件的访问路由,这样Django才能处理media文件的下载请求:

from django.conf import settings
from django.conf.urls.static import static
from django.urls import path, include

urlpatterns = [
    # 其他路由,比如你的app路由
    path('api/', include('yourapp.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

二、实现文件上传+文件列表的视图

接下来用DRF写一个视图,同时处理文件上传的POST请求和返回文件列表的GET请求。在你的app里创建/修改views.py:

from django.conf import settings
from django.core.files.storage import default_storage
from django.http import JsonResponse
from rest_framework.views import APIView
from rest_framework.parsers import MultiPartParser, FormParser
from rest_framework.response import Response
from rest_framework import status
import os

class MediaFileView(APIView):
    # 处理文件上传需要的解析器
    parser_classes = (MultiPartParser, FormParser)

    def get(self, request):
        # 遍历media目录下的所有文件,生成指定格式的JSON
        media_files = {}
        file_index = 1
        for filename in os.listdir(settings.MEDIA_ROOT):
            file_path = os.path.join(settings.MEDIA_ROOT, filename)
            # 只处理文件,跳过子目录
            if os.path.isfile(file_path):
                # 生成文件的绝对访问链接
                file_url = request.build_absolute_uri(f"{settings.MEDIA_URL}{filename}")
                media_files[f'file{file_index}'] = file_url
                file_index += 1
        return JsonResponse(media_files)

    def post(self, request):
        # 获取上传的文件
        uploaded_file = request.FILES.get('file')
        if not uploaded_file:
            return Response({"error": "No file uploaded"}, status=status.HTTP_400_BAD_REQUEST)
        
        # 保存文件到media目录
        file_path = os.path.join(settings.MEDIA_ROOT, uploaded_file.name)
        # 可选:避免文件名重复,这里做了简单的冲突检查,你可以改成自动重命名逻辑
        if default_storage.exists(file_path):
            return Response({"error": "File already exists"}, status=status.HTTP_409_CONFLICT)
        
        default_storage.save(file_path, uploaded_file)
        # 返回上传成功的信息和文件链接
        file_url = request.build_absolute_uri(f"{settings.MEDIA_URL}{uploaded_file.name}")
        return Response({"message": "File uploaded successfully", "file_url": file_url}, status=status.HTTP_201_CREATED)

这里的关键点:

  • GET方法会自动遍历media目录,生成{"file1": "链接", "file2": "链接"}格式的响应,编号随文件数量自动递增。
  • POST方法支持单文件上传,同时做了基础的文件名冲突检查,你可以根据需求扩展(比如给重复文件名加时间戳后缀)。

三、配置视图的路由

在你的app的urls.py里添加路由,把刚才的视图映射到URL:

from django.urls import path
from .views import MediaFileView

urlpatterns = [
    path('media-files/', MediaFileView.as_view(), name='media-files'),
]

四、测试功能

现在可以验证功能了:

  1. 获取文件列表:发送GET请求到http://你的域名/api/media-files/,如果media目录有2个文件,会返回:
    {"file1": "http://你的域名/media/example1.txt", "file2": "http://你的域名/media/example2.txt"}
    
  2. 上传文件:用POST请求(multipart/form-data格式)发送文件到同一个URL,参数名填file,成功后会返回文件的访问链接。
  3. 下载文件:直接访问返回的文件链接,就能下载media目录里的文件了。

额外提醒

  • 如果需要权限控制(比如只允许登录用户访问),可以给视图添加DRF的权限类,比如permission_classes = [IsAuthenticated]。
  • 生产环境下,建议用Nginx或其他静态文件服务器处理media文件的访问,不要依赖Django自带的static路由(性能较差)。
  • 如果media目录文件很多,可以给GET请求添加分页逻辑,避免返回过大的响应。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:30:11