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

- 视图函数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实现的文件上传
。。。。。。待定,之后再继续补充
本文详细介绍了在Django中实现文件上传的四种方法:简单的文件上传、修改上传图标、基于Form表单的上传以及基于Ajax的实现。强调了在处理文件上传时,需要注意表单的enctype属性及如何通过request.FILES获取上传文件。还提到可以通过修改样式来改变上传按钮的外观。
3162

被折叠的 条评论
为什么被折叠?



