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编写一个国际象棋AI程序
Nov 28 Python
更改Python命令行交互提示符的方法
Jan 14 Python
用Django实现一个可运行的区块链应用
Mar 08 Python
解决python删除文件的权限错误问题
Apr 24 Python
面向初学者的Python编辑器Mu
Oct 08 Python
解决python opencv无法显示图片的问题
Oct 28 Python
Python面向对象基础入门之编码细节与注意事项
Dec 11 Python
python2.7实现邮件发送功能
Dec 12 Python
django数据库自动重连的方法实例
Jul 21 Python
Django单元测试工具test client使用详解
Aug 02 Python
Python 用三行代码提取PDF表格数据
Oct 13 Python
Python远程开发环境部署与调试过程图解
Dec 09 Python
python3 删除所有自定义变量的操作
Apr 08 #Python
pytorch显存一直变大的解决方案
Apr 08 #Python
Python文件的操作示例的详细讲解
Django展示可视化图表的多种方式
python tkinter模块的简单使用
python如何在word中存储本地图片
python 下载文件的几种方式分享
Apr 07 #Python
You might like
function.inc.php超越php
2006/12/09 PHP
php 读取shell管道传输过来的内容
2010/03/01 PHP
php使用smtp发送支持附件的邮件示例
2014/04/13 PHP
php多线程实现方法及用法实例详解
2015/10/26 PHP
PHP tp5中使用原生sql查询代码实例
2020/10/28 PHP
浅析JavaScript中的同名标识符优先级
2013/12/06 Javascript
Javascript数据结构与算法之列表详解
2015/03/12 Javascript
基于Bootstrap实现的下拉菜单手机端不能选择菜单项的原因附解决办法
2016/07/22 Javascript
深入浅出ES6之let和const命令
2016/08/25 Javascript
微信小程序 绘图之饼图实现
2016/10/24 Javascript
ES6概念 Symbol toString()方法
2016/12/25 Javascript
利用Jquery实现几款漂亮实用的时间轴(附示例代码)
2017/02/15 Javascript
jquery.guide.js新版上线操作向导镂空提示jQuery插件(推荐)
2017/05/20 jQuery
JS异步函数队列功能实例分析
2017/11/28 Javascript
js input输入百分号保存数据库失败的解决方法
2018/05/26 Javascript
三分钟教你用Node做一个微信哄女友(基友)神器(面向小白)
2019/06/21 Javascript
如何在Angular8.0下使用ngx-translate进行国际化配置
2019/07/24 Javascript
Vue绑定用户接口实现代码示例
2020/11/04 Javascript
vue实现简易的双向数据绑定
2020/12/29 Vue.js
[16:43]Heroes19_剃刀(完美)
2014/10/31 DOTA
SublimeText 2编译python出错的解决方法(The system cannot find the file specified)
2013/11/27 Python
Python操作CouchDB数据库简单示例
2015/03/10 Python
python 3.7.0 安装配置方法图文教程
2018/08/27 Python
tensorflow实现在函数中用tf.Print输出中间值
2020/01/21 Python
Python中求对数方法总结
2020/03/10 Python
html5 offlline 缓存使用示例
2013/06/24 HTML / CSS
html5教你做炫酷的碎片式图片切换 (canvas)
2017/07/28 HTML / CSS
数据库笔试题
2013/05/09 面试题
一些Unix笔试题和面试题
2013/01/22 面试题
思想品德自我评价
2014/02/04 职场文书
食堂厨师岗位职责
2014/08/25 职场文书
学校党员对照检查材料
2014/08/28 职场文书
干部竞争上岗演讲稿
2014/09/11 职场文书
教师病假条范文
2015/08/17 职场文书
《狼牙山五壮士》读后感:宁死不屈,视死如归
2019/08/16 职场文书
Win11无法安装更新补丁KB3045316怎么办 附KB3045316补丁修复教程
2022/08/14 数码科技