django文件上传功能的实现

Y11


1、 创建新app,配置路由和settings(Y10博客有具体操作)


2、创建一个上传页面(html),在views中渲染页面,配置路由,配置css,引入css,引入共享文件jquery


3、创建common_static共享文件目录,templates/app前端页面目录,static静态文件目录。 另外还要创建文件传入后要存储和读取的目录,如存取img,即创建file/img


4、在views中定义函数完成文件上传后存储的功能
(1)引入csrf验证模块,from django.views.decorators.csrf import csrf_exempt
(2)@csrf_exempt
(3)具体功能实现

def deal_file(request):
    # 获取前端传输的文件对象
    file_obj = request.FILES.get('file')
    # 获取文件类型
    img_type = file_obj.name.split('.')[1]
    # 将文件类型中的数据大写全部转换成小写
    img_type = img_type.lower()
    if img_type in ['png','jpg','jpeg','gif']:
        # 将图片存到指定目录
        # 获取当前时间的时间戳
        timestr = str(time.time()).replace('.','')
        # 获取程序需要写入的文件路径
        path = os.path.join(settings.BASE_DIR, 'app2/file/img/{0}{1}'.format(timestr, file_obj.name))
        # 根据路径打开指定的文件(以二进制读写方式打开)
        f = open(path,'wb+')
        # chunks将对应的文件数据转换成若干片段, 分段写入, 可以有效提
        高文件的写入速度, 适用于2.5M以上的文件
        for chunk in file_obj.chunks():
            f.write(chunk)
        f.close()
        msg = {'code':200, 'url':'http://127.0.0.1:8000/app2/pass_data/{0}
        {1}'.format(timestr,file_obj.name), 'error':''}
    else:
        # 存储失败, 返回错误信息
        msg = {'code':305, 'url':'', 'error':'暂不支持该类型'}
    return HttpResponse(json.dumps(msg))
# 定义函数完成指定服务器向前端返回指定文件
def pass_img_data(request, img_name):
    path = os.path.join(settings.BASE_DIR, 'app2/file/img/{0}'.format(img_name))
    if os.path.exists(path):
#         # 文件存在, 读取文件数据
        f = open(path, 'rb+')
        data = f.read()
        f.close()
        return HttpResponse(data)
    else:
        return HttpResponse('')

注意
(1) 获取文件对象:file_obj = request.FILES.get(‘file’),其中注意文件获取需要.FILES
(2) 导入time模块, 利用时间戳给每一张图片设定唯一名字
(3) 通过.format将时间戳和图片名字拼接一起
(4) 文件写入必须是二进制方式写入
(5) chunks将对应的文件数据转换成若干片段, 分段写入, 可以有效提高文件的写入速度, 适用于2.5M以上的文件


5、在urls.py中配置对应路由

from django.contrib import admin
from django.urls import path
from . import views
urlpatterns = [
    path('upload/', views.render_upload, name="upload"),
    path('deal_file/<str:account>/', views.deal_file, name="deal_file"),
    path('pass_data/<str:account>/<str:img_name>/', views.pass_img_data, name="pass_data"),
]

6、在传入页面中,写JS代码

<script src="{%static 'js/jquery.min.js'%}"></script>
<script src="{%static 'js/csrf.js'%}"></script>
<script type="text/javascript">
    // 该事件用来监听文件上传控件是否选择好指定文件
    $('#file').on('change',function () {
        //获取文件选择控件选择的图片对象
        //let file_c = document.getElementById('file');
        let file_c = $('#file').get(0);
        // files是input[type=file]的属性, 用来存储文件选择控件选择的图片对象, 是一个数组类型
        let file_obj = file_c.files[0];
        // 将文件类型的数据打包成form表单数据
        let formD = new FormData();
        formD.append('file',file_obj);
        //正式进行数据传输
        create_csrf(); //生成csrf——token
        $.ajax({
            url:'{%url "deal_file"%}',
            type:'post',
            data:formD,
            // 数据传输过程中不需要将数据转换成字符串
            processData:false,
            // ajax传输数据过程中不需要重新设置数据的编码格式
            contentType:false,
            success:function (res) {
                let msg = JSON.parse(res);
                if(msg.code == 200){
                    $('#photo').attr('src',msg.url);
                }else {
                    alert(msg.error);
                }
            }
        });
    });

注意:在文件上传时,form表单的数据传输方式必须为post, 并且编码格式为multipart/form-data, 否则服务器是无法获取传输的文件数据

<form method="post" enctype="multipart/form-data">

若需要查看具体代码,在此分享本人创建过的供学习的django工程(以上为工程django_2):
链接:https://pan.baidu.com/s/1v74l_n_1F5WoRxOb7YlRjg
提取码:ev9p


个人小结,定有不足之处,欢迎指点。
谢谢~

猜你喜欢

转载自blog.csdn.net/qq_43317529/article/details/83037690