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

Django后端自动上传文件到FileField无需前端手动选择实现方法

实现方案

核心逻辑是访问接口时由后端直接读取服务器本地预存的data1.py文件,通过Django内置的File类封装后赋值给Result模型的File字段完成入库,全程不需要前端选择、上传文件流。

前置配置

先修正原有代码的问题,同时配置好Django文件存储的必要参数:

  • 首先在项目settings.py中补充媒体文件和本地预存文件目录配置,确保FileField正常工作,同时规避路径遍历风险:
import os
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent

# 原有配置保留,新增以下内容
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
# 本地预存文件的白名单根目录,手动创建该文件夹后将data1.py放入其中
LOCAL_PRESET_FILE_ROOT = os.path.join(BASE_DIR, 'local_preset_files')
  • 原代码直接将模型类Result传给serializer_class是错误用法,需要先在result应用下新建serializers.py编写对应序列化器:
from rest_framework import serializers
from .models import Result

class ResultSerializer(serializers.ModelSerializer):
    class Meta:
        model = Result
        fields = '__all__'

接口代码改造

修改views.py中的视图类代码,补充路径校验、本地文件读取、模型保存逻辑:

原接口使用GET方法做数据写入不符合HTTP语义,这里调整为POST方法,若坚持使用GET也可正常运行,但不推荐。

import os
from django.core.files import File
from rest_framework.response import Response 
from rest_framework.decorators import action
from rest_framework import viewsets,status
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated
from django.conf import settings
from .models import Result
from .serializers import ResultSerializer

class ResultViewSet(viewsets.ModelViewSet):
    queryset = Result.objects.all()
    serializer_class = ResultSerializer
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)

    # 该接口不需要传入pk,detail设为False
    @action(detail=False, methods=['POST'])
    def resultfill(self, request):
        # 固定使用data1.py的话可以直接写死文件名,不需要前端传参
        file_name = request.data.get('file_name', 'data1.py')
        target_file_path = os.path.join(settings.LOCAL_PRESET_FILE_ROOT, file_name)
        
        # 安全校验:强制校验文件路径在白名单目录内,防止路径遍历攻击
        real_file_path = os.path.realpath(target_file_path)
        if not real_file_path.startswith(os.path.realpath(settings.LOCAL_PRESET_FILE_ROOT)):
            return Response({'error': '非法文件路径'}, status=status.HTTP_400_BAD_REQUEST)
        
        # 校验文件存在性
        if not os.path.isfile(real_file_path):
            return Response({'error': '指定文件不存在'}, status=status.HTTP_404_NOT_FOUND)
        
        # 读取本地文件封装为Django文件对象,创建数据库记录
        with open(real_file_path, 'rb') as f:
            django_file = File(f)
            result_obj = Result.objects.create(
                Name='预设数据文件', # Name字段可根据业务需求自行赋值
                File=django_file
            )
        
        serializer = self.get_serializer(result_obj)
        return Response(serializer.data, status=status.HTTP_201_CREATED)

注意事项

  • 如果固定使用data1.py,可以去掉file_name参数获取逻辑,直接写死文件路径,访问接口即可自动完成文件入库,不需要传任何文件相关参数。
  • 路径安全校验必须保留,禁止直接读取前端传入的任意路径,否则会产生任意文件读取、服务器敏感信息泄露的高危漏洞。
  • 保存时Django会自动将原文件拷贝到MEDIA_ROOT配置的目录下,不会修改或移动原路径下的data1.py。
  • 开发环境下需要在项目根urls.py中补充媒体文件路由,否则保存后的文件无法通过URL访问:
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    # 原有路由配置保持不变
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 19:15:46