Django文件上传和下载
2017-08-20 22:02
501 查看
对于Web应用,经常需要实现文件的上传和下载,今天就来介绍一下使用Django如何实现文件的上传和下载。
先来创建一个Django项目,名称为FileService:
django-admin startproject FileService
创建应用fileoperation
python3 manage.py startapp fileoperation
在项目的FileService/settings.py中的INSTALLED_APPS中添加fileoperation应用
INSTALLED_APPS = [
......
'fileoperation',
]
在项目的fileoperation/目录下创建目录templates目录,用于放置模板,创建模板home.html
模板很简单,主要是实现了一个enctype为multipart/form-data的form,将表单提交到upload请求,然后页面会显示当前已经上传的文件,点击条目,可以进行文件下载,这样我们就可以通过页面进行上传和下载了。
配置FileService/urls.py文件,这里为了简便,我没有将url配置在fileoperation目录下的urls.py,而是直接使用fileoperation包下的views.py。
前两个配置,如果看过之前的文章应该很好理解,这里重点看一下download请求的正则表达式,其后使用
(?P<filename>.+)
构建了一个带有路径参数的url,用来表示该url后会跟一个文件名,例如,如果我文件名为a.txt,则url会是
download/a.txt
其中a.txt会作为filename参数,赋值给我们views.download函数的filename参数,稍后就会看到。
下面看一下fileoperation/views.py的内容,首先是import部分,其中还定义了一个全局变量,表示保存文件的路径,require_GET和require_POST是两个修饰符,用来规定对应的视图函数只能执行GET或POST请求
下面是一个函数,用来渲染home.html模板
home请求的视图函数
比较简单,判断是否存在保存文件的目录,如果不存在,创建该目录,然后渲染home.html模板。
download视图函数
下载流程很简单,打开需要下载的文件,filename参数就是前面url配置的路径参数,将Python的文件对象使用Django的文件对象进行包裹,然后创建HttpResponse对象,给该对象传入chunks()返回的生成器,该生成器每次生成最多64kb的文件数据,然后传输给客户端。
上传视图函数
上传的逻辑也不复杂,从request的FILES中取到filename对应的django file对象,然后创建输出文件,将django file对象的chunks写入输出文件。
可以看到,Django实现上传和下载非常简单,代码也比较简洁,而且,使用chunks直接可以实现大文件上传,而不必担心占用过多的内存。
先来创建一个Django项目,名称为FileService:
django-admin startproject FileService
创建应用fileoperation
python3 manage.py startapp fileoperation
在项目的FileService/settings.py中的INSTALLED_APPS中添加fileoperation应用
INSTALLED_APPS = [
......
'fileoperation',
]
在项目的fileoperation/目录下创建目录templates目录,用于放置模板,创建模板home.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>上传下载</title> </head> <body> <form action="{% url 'upload'%}" enctype="multipart/form-data" method="post"> {% csrf_token %} <input type="file" name="filename" value=""> <input type="submit" value="上传"> </form> <ul> {% for file in files %} <li><a href="{% url 'download' file %}">{{ file }}</a></li> {% endfor %} </ul> </body> </html>
模板很简单,主要是实现了一个enctype为multipart/form-data的form,将表单提交到upload请求,然后页面会显示当前已经上传的文件,点击条目,可以进行文件下载,这样我们就可以通过页面进行上传和下载了。
配置FileService/urls.py文件,这里为了简便,我没有将url配置在fileoperation目录下的urls.py,而是直接使用fileoperation包下的views.py。
from django.conf.urls import url from fileoperation import views urlpatterns = [ url(r'^$', views.home, name='home'), url(r'^upload/$', views.upload, name='upload'), url(r'^download/(?P<filename>.+)$', views.download, name='download'), ]
前两个配置,如果看过之前的文章应该很好理解,这里重点看一下download请求的正则表达式,其后使用
(?P<filename>.+)
构建了一个带有路径参数的url,用来表示该url后会跟一个文件名,例如,如果我文件名为a.txt,则url会是
download/a.txt
其中a.txt会作为filename参数,赋值给我们views.download函数的filename参数,稍后就会看到。
下面看一下fileoperation/views.py的内容,首先是import部分,其中还定义了一个全局变量,表示保存文件的路径,require_GET和require_POST是两个修饰符,用来规定对应的视图函数只能执行GET或POST请求
from django.shortcuts import render from django.views.decorators.http import require_GET, require_POST from django.http import HttpResponse from django.core.files import File import os SAVED_FILES_DIR = r'files/'
下面是一个函数,用来渲染home.html模板
def render_home_template(request): files = os.listdir(SAVED_FILES_DIR) return render(request, 'home.html', {'files': files})
home请求的视图函数
@require_GET def home(request): if not os.path.exists(SAVED_FILES_DIR): os.makedirs(SAVED_FILES_DIR) return render_home_template(request)
比较简单,判断是否存在保存文件的目录,如果不存在,创建该目录,然后渲染home.html模板。
download视图函数
@require_GET def download(request, filename): file_pathname = os.path.join(SAVED_FILES_DIR, filename) with open(file_pathname, 'rb') as f: file = File(f) response = HttpResponse(file.chunks(), content_type='APPLICATION/OCTET-STREAM') response['Content-Disposition'] = 'attachment; filename=' + filename response['Content-Length'] = os.path.getsize(file_pathname) return response
下载流程很简单,打开需要下载的文件,filename参数就是前面url配置的路径参数,将Python的文件对象使用Django的文件对象进行包裹,然后创建HttpResponse对象,给该对象传入chunks()返回的生成器,该生成器每次生成最多64kb的文件数据,然后传输给客户端。
上传视图函数
@require_POST def upload(request): file = request.FILES.get("filename", None) if not file: return render_home_template(request) pathname = os.path.join(SAVED_FILES_DIR, file.name) with open(pathname, 'wb+') as destination: for chunk in file.chunks(): destination.write(chunk) return render_home_template(request)
上传的逻辑也不复杂,从request的FILES中取到filename对应的django file对象,然后创建输出文件,将django file对象的chunks写入输出文件。
可以看到,Django实现上传和下载非常简单,代码也比较简洁,而且,使用chunks直接可以实现大文件上传,而不必担心占用过多的内存。
相关文章推荐
- Django实现文件上传下载
- Django-文件上传与下载(FileFlid)
- 8. Django系列之上传文件与下载-djang为服务端,requests为客户端
- Django文件的上传与下载
- django 文件上传(阿里云oss)下载(支持大文件下载)
- django上传下载大文件
- django文件上传下载
- thinkphp3.2.3文件上传下载及去重
- SpringBoot文件上传下载和多文件上传(图文详解)
- ftp文件上传和下载
- Python实现简易文件服务器 包含上传下载删除新建目录功能
- Struts2文件上传下载
- springmvc文件上传下载
- Struts2之文件上传与下载
- 文件的上传以及下载
- struts2 文件上传与下载原理
- JavaWeb学习总结(五十)——文件上传和下载
- Struts2实现文件上传和下载,多文件上传,限制文件大小,限制文件类型
- javaweb工程 servlet文件上传与下载