Django 如何实现文件上传下载


Posted in Python onApril 08, 2021

1. 前言

大家好,我是安果!

文件上传、下载作为基础功能,在 Web 项目中非常普遍,Django 项目如何实现文件上传下载?

本篇文章将带大家 5 分钟快速实现文件上传下载功能

2. 实战一下

详细实现步骤如下( 9 步)

2-1  进入虚拟环境,创建一个项目及 App

workon django3

# 创建项目
django-admin startproject file_up_and_down_demo

# 进入项目根目录
cd file_up_and_down_demo/

# 创建一个App
django-admin startapp index

2-2  创建模板目录并配置 settings.py

在 index App 下创建一个 templates 文件夹,然后在项目配置文件 settings.py 中配置 App 及模板目录

# settings.py

# 配置App
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'index',
]

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            # 配置模板目录
            os.path.join(BASE_DIR, 'index/templates')
        ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

2-3  创建文件模型,并映射到数据库

以默认的 sqlite 为例,在 index App 下的 models.py 中自定义一个代表文件的模型

该模型包含 3 个字段:

  • 文件名称
  • 文件保存路径
  • 上传时间
# index App models.py

from django.db import models
from django.utils import timezone


# 文件模型
class FileModel(models.Model):
    # 文件名称
    name = models.CharField(max_length=50)

    # 文件保存路径
    path = models.CharField(max_length=100)

    # 上传时间
    upload_time = models.DateTimeField(default=timezone.now)

然后,在项目根目录下执行下面 2 条命令,将模型结构映射到数据库中

# 数据库映射
Python3 manage.py makemigrations

python3 manage.py migrate

2-4  自定义表单控件

在 index App 下创建一个表单文件 forms.py

在内部自定义一个表单类,继承于 forms.Form

# index App forms.py

from django import forms

class FileForm(forms.Form):
    file = forms.FileField(
        # 支持多文件上传
        widget=forms.ClearableFileInput(attrs={'multiple': True}),
        label='请选择文件',
    )

2-5  添加上传、下载路由 URL

为上传、下载功能添加路由 URL

# 项目urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('index.urls'))
]

# index App urls.py
from django.urls import path

from .views import *

urlpatterns = [
    # 上传
    path('', index_view, name='index'),

    # 下载
    path('download/<id>', download_view, name='download')
]

2-6  编写模板文件

在 index App 的模板文件夹创建一个简单的模板文件 upload.html

其中

  • form 代表视图函数传过来的表单实体对象
  • form.as_p 代表以字段格式渲染所有的表单元素
# index App upload.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>主页-上传文件</title>
</head>
<body>

<form method="post" enctype="multipart/form-data">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="确定上传">
</form>

</body>
</html>

2-7  上传视图函数

在 index App 下的 views.py 中编写上传功能的视图函数

需要注意的是,我们需要提前在项目根目录创建一个 upload 文件夹,用于存放上传的文件

# index App views.py

def index_view(request):
    """
    上传文件
    :param request:
    :return:
    """
    if request.method == 'POST':
        form = FileForm(request.POST, request.FILES)
        if form.is_valid():
            # 选择的文件
            files = request.FILES.getlist('file')

            # 遍历写入到数据库中
            for file in files:
                # 写入到数据库中
                file_model = FileModel(name=file.name, path=os.path.join('./upload', file.name))
                file_model.save()

                # 写入到服务器本地
                destination = open(os.path.join("./upload", file.name), 'wb+')
                for chunk in file.chunks():
                    destination.write(chunk)
                destination.close()

            # 提示上传成功
            return HttpResponse('上传成功!')
    else:
        form = FileForm()
        return render(request, 'upload.html', locals())

2-8  下载视图函数

接着,编写下载功能的视图函数

# index App views.py

def download_view(request, id):
    """
    下载文件
    :param request:
    :param id:文件id
    :return:
    """
    file_result = FileModel.objects.filter(id=id)

    # 如果文件存在,就下载文件
    if file_result:

        file = list(file_result)[0]

        # 文件名称及路径
        name = file.name
        path = file.path

        # 读取文件
        file = open(path, 'rb')
        response = FileResponse(file)

        # 使用urlquote对文件名称进行编码
        response['Content-Disposition'] = 'attachment;filename="%s"' % urlquote(name)

        return response
    else:
        return HttpResponse('文件不存在!')

2-9  运行并测试

运行项目,访问下面的地址,并上传一个文件

使用 Pycharm 打开 sqlite 数据库,发现成功插入一条文件记录,并且文件也上传到 upload 文件夹下

接着访问下面的地址实现文件下载功能「 其中,file_id 代表文件的 id 值 」

http://127.0.0.1:8000/download/file_id

3. 最后

文章通过一个简单的例子实现了文件的上传、下载功能,并同步文件记录到数据库

实际项目中,一般还包含文件列表、文件删除等功能,这些功能只需要结合数据库来增删查改即可实

代码地址:https://github.com/xingag/python_web

以上就是Django 如何实现文件上传下载的详细内容,更多关于Django实现文件上传下载的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
python中查找excel某一列的重复数据 剔除之后打印
Feb 10 Python
python调用新浪微博API项目实践
Jul 28 Python
Python比较文件夹比另一同名文件夹多出的文件并复制出来的方法
Mar 05 Python
python数字图像处理实现直方图与均衡化
May 04 Python
Python用5行代码写一个自定义简单二维码
Oct 21 Python
python3用PIL把图片转换为RGB图片的实例
Jul 04 Python
python实现图片九宫格分割
Mar 07 Python
解决Tensorflow 内存泄露问题
Feb 05 Python
python通过函数名调用函数的几种场景
Sep 23 Python
用python开发一款操作MySQL的小工具
May 12 Python
Python中的协程(Coroutine)操作模块(greenlet、gevent)
May 30 Python
python实现一个简单的贪吃蛇游戏附代码
Jun 28 Python
python3 删除所有自定义变量的操作
Apr 08 #Python
pytorch显存一直变大的解决方案
Apr 08 #Python
Python文件的操作示例的详细讲解
Django展示可视化图表的多种方式
python tkinter模块的简单使用
python如何在word中存储本地图片
python 下载文件的几种方式分享
Apr 07 #Python
You might like
php使用iconv中文截断问题的解决方法
2015/02/11 PHP
PHP实现的基于单向链表解决约瑟夫环问题示例
2017/09/30 PHP
浅谈使用 Yii2 AssetBundle 中 $publishOptions 的正确姿势
2017/11/08 PHP
laravel Task Scheduling(任务调度)在windows下的使用详解
2019/10/22 PHP
JAVASCRIPT keycode总结
2009/02/04 Javascript
鼠标经过的文本框textbox变色
2009/05/21 Javascript
js getBoundingClientRect() 来获取页面元素的位置
2010/11/25 Javascript
用js来解决ajax读取页面乱码
2010/11/28 Javascript
jQuery ajax 路由和过滤器使用说明
2011/08/02 Javascript
js格式化货币数据实现代码
2013/09/04 Javascript
关闭时刷新父窗口两种方法
2014/05/07 Javascript
实现网页页面跳转的几种方法(meta标签、js实现、php实现)
2014/05/20 Javascript
javascript常见数据验证插件大全
2015/08/03 Javascript
jquery+html5时钟特效代码分享(可设置闹钟并且语音提醒)
2020/03/30 Javascript
基于Javascript实现二级联动菜单效果
2016/03/04 Javascript
AngularJS 获取ng-repeat动态生成的ng-model值实例详解
2016/11/29 Javascript
利用jquery实现验证输入的是否是数字、小数,包含保留几位小数
2016/12/07 Javascript
jQuery实现拖动效果的实例代码
2017/06/25 jQuery
详解wepy开发小程序踩过的坑(小结)
2019/05/22 Javascript
原生js实现日历效果
2020/03/02 Javascript
下载给定网页上图片的方法
2014/02/18 Python
python网络编程学习笔记(一)
2014/06/09 Python
深入浅析Python字符编码
2015/11/12 Python
python如何从文件读取数据及解析
2019/09/19 Python
Python爬取数据并实现可视化代码解析
2020/08/12 Python
Django启动时找不到mysqlclient问题解决方案
2020/11/11 Python
使用html5 canvas创建太空游戏的示例
2014/05/08 HTML / CSS
服装设计专业毕业生求职信
2014/04/09 职场文书
应聘英语教师求职信
2014/04/24 职场文书
做一个有道德的人活动实施方案
2014/08/23 职场文书
学生偷窃检讨书
2014/09/25 职场文书
精神文明建设先进个人事迹材料
2014/12/24 职场文书
庆元旦主持词
2015/07/06 职场文书
《语言的突破》读后感3篇
2019/12/12 职场文书
MySQL 使用事件(Events)完成计划任务
2021/05/24 MySQL
Java 泛型详解(超详细的java泛型方法解析)
2021/07/02 Java/Android