Django框架(十、文件上传)

本文详细介绍了在Django中实现文件上传的四种方法:简单的文件上传、修改上传图标、基于Form表单的上传以及基于Ajax的实现。强调了在处理文件上传时,需要注意表单的enctype属性及如何通过request.FILES获取上传文件。还提到可以通过修改样式来改变上传按钮的外观。

一、简单的文件上传

在现实的生产环境中,有许多时候我们需要用到上传下载。其实在Django中已经预料到了我们需要该操作,因此它也给我们提供了一些简单的方法。
用Django实现文件上传并且保存到指定路径下,其实并不困难,完全不需要用到django的forms,也不需要django的models,就可以实现,下面开始实现。

  1. 模板文件html
    在模板文件中,创建一个form表单,需要特别注意的是,在有文件上传的form表单中,method属性必须为post,而且 必须指定它的enctype为"multipart/form-data"表明不对字符进行编码,具体的代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }
        
    </style>
</head>
<body>
<form action="/upload/" method="post" enctype="multipart/form-data">
    {% csrf_token %}
    <p>用户名:<input type="text" name="user"></p>
    <p>文件:<input type="file" name="files" id="files"></p>
    <p><input type="submit" value="提交"></p>
</form>
</body>
</html>
  • 效果图:
    在这里插入图片描述
  1. 视图函数view.py

首先我们先上代码:

def upload(request):
    if request.method == 'GET':
        return render(request, "upload.html")
    else:
        user = request.POST.get("user")
        
        # 此时的获取的files是一个对象,而不是一个字符串,该对象包含文件大小、文件名、文件内容
        files = request.FILES.get("files")
        print(files)
        print(type(files))
        print("files_name:", files.name)
        print("files_size:", files.size)
        
        f = open(files.name, "wb")
        if files.multiple_chunks():
            for line in files.chunks():
                f.write(line)
        else:
            f.write(files.read())
        f.close()
        
        return HttpResponse("OK")

django帮我们实现了主要的功能,因此我们写上传文件时的代码并不长。但我们依然需要理解这些代码。
虽然我们在上传文件的时候用的时post方法进行上传,但我们不能跟之前获取字段值一样,不能通过reqeust.POST.get(“files”)的获取上传的文件。对于文件上传,Django进行了特殊的处理,我们需要使用另一种方式来进行获取,
request.FILES.get(“files”)
假设以上传一个名为 alice.png文件,我们可以发现 files是我们上传的文件名,而且files是一个类对象。通过调用name()方法能够获取文件名,siez()方法能够获取文件大小。
在这里插入图片描述

此时,上传文件并没有完成的,django只是帮我们获取了文件,将文件存放到了内存中,没有写到硬盘里面去,接下里需要完成的就是把文件写入到硬盘,那我们就需要将文件写到硬盘中,这样才算完成了文件的上传。
将上传之前,我们先来了解下Django中为我们提供的几个方法属性。

属性或方法描述
read()从文件中读取整个上传的数据,这个方法只适合小文件
chunks()以迭代器的方式,按块返回文件,通过在for循环中进行迭代,可以将大文件按块写入到服务器中;
multiple_chunks()根据上传文件files的大小,返回True或者False,当files文件大于2.5M(默认为2.5M,可以调整)时,该方法返回True,否则返回False
name这是一个属性,不是方法,该属性得到上传的文件名,包括后缀。
size这也是一个属性,该属性得到上传文件的大小。单位为字节

chunk()方法能够帮我们将文件分块,每次只返回一部分给服务器,这样的话就能避免文件过大时,占用大量的系统资源。
在实际生产环境中,我们会用multiple_chunks()来判断大文件还是小文件,如果是小文件,直接读取整个文件,然后保存在系统中。

二、文件上传图标修改

在这里插入图片描述

文件上传这个按钮是由html为我们提供的一个模板,但它长得实在是太丑了,影响我们的审美,但是该按钮的字样我们并不能css渲染,修改图标。
这就很郁闷了,我们总不能老是看着它吧。。。
其实方法还是有的,该标签能够通过css渲染它的大小(例如高度和宽度)以及它的透明度。那么我们就可以通过将它的透明度修改为0,然后在该标签之上覆盖我们需要的图片,那么这就看上去修改了该按钮的样式了。
上代码:

    <div style="position: relative;" >
        <span style="width: 75px;background-color: red;border-style: solid">    NB的上传</span >
        <input type="file" name="files"
               style="opacity: 0;position: absolute;top: 0;left: 0;width: 75px">

    </div>

我们只需要修改样式,将html提供的input框将它的透明度设置为0,宽度和高度设置成跟我们需要的格式一样大小,这样便能完成系统不可修改的格式。

三、基于Form表单的上传

通过form表单来实现文件上传,其实该方法的本质是不变的

from django.shortcuts import render
from django.shortcuts import HttpResponse

# Create your views here.

from django import forms
from django.forms import fields

class UploadForm(forms.Form):
    user = fields.CharField()
    files = fields.FileField()

def upload(request):
    if request.method == 'GET':
        upload_obj = UploadForm(request.POST,request.FILES)
        return render(request, "upload.html",{"upload_obj ":upload_obj })
    else:
        upload_obj = UploadForm(request.POST,request.FILES)
        if upload_obj.is_valid():
            user = upload_obj.cleaned_data["user"]
            files = upload_obj.cleaned_data["files"]
        # 此时的获取的files是一个对象,而不是一个字符串,该对象包含文件大小、文件名、文件内容
        f = open(files.name, "wb")
        if files.multiple_chunks():
            for line in files.chunks():
                f.write(line)
        else:
            f.write(files.read())
        f.close()
        return HttpResponse("OK")

所以该方法的本质是一样的,只不过form表单实现的的话能够帮我们验证表单传入的数据。同时还可以做文件类型的限制,在这里我们就不过多的叙述了。

四、基于ajax实现的文件上传

。。。。。。待定,之后再继续补充

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值