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的setuptools框架下生成egg的教程
Apr 13 Python
Python中的深拷贝和浅拷贝详解
Jun 03 Python
使用Python生成XML的方法实例
Mar 21 Python
python itchat实现微信好友头像拼接图的示例代码
Aug 14 Python
分析python动态规划的递归、非递归实现
Mar 04 Python
Pandas之drop_duplicates:去除重复项方法
Apr 18 Python
Python爬虫基础之XPath语法与lxml库的用法详解
Sep 13 Python
python3中替换python2中cmp函数的实现
Aug 20 Python
python实现复制大量文件功能
Aug 31 Python
python 指定源路径来解决import问题的操作
Mar 04 Python
浅谈Python3中datetime不同时区转换介绍与踩坑
Aug 02 Python
python人工智能human learn绘图可创建机器学习模型
Nov 23 Python
python3 删除所有自定义变量的操作
Apr 08 #Python
pytorch显存一直变大的解决方案
Apr 08 #Python
Python文件的操作示例的详细讲解
Django展示可视化图表的多种方式
python tkinter模块的简单使用
python如何在word中存储本地图片
python 下载文件的几种方式分享
Apr 07 #Python
You might like
JAVA/JSP学习系列之四
2006/10/09 PHP
说明的比较细的php 正则学习实例
2008/07/30 PHP
php中sprintf与printf函数用法区别解析
2014/02/17 PHP
PHP数组生成XML格式数据的封装类实例
2016/11/10 PHP
用户注册常用javascript代码
2009/08/29 Javascript
基于JQuery.timer插件实现一个计时器
2010/04/25 Javascript
jQuery中has()方法用法实例
2015/01/06 Javascript
javascript轻量级库createjs使用Easel实现拖拽效果
2016/02/19 Javascript
Bootstrapvalidator校验、校验清除重置的实现代码(推荐)
2016/09/28 Javascript
KnockoutJS 3.X API 第四章之表单submit、enable、disable绑定
2016/10/10 Javascript
单行 JS 实现移动端金钱格式的输入规则
2017/05/22 Javascript
vue用递归组件写树形控件的实例代码
2018/07/19 Javascript
webpack4简单入门实例
2018/09/06 Javascript
vue2.0结合Element-ui实战案例
2019/03/06 Javascript
原生JS实现随机点名项目的实例代码
2019/04/30 Javascript
详解js中的原型,原型对象,原型链
2020/07/16 Javascript
JS PHP字符串截取函数实现原理解析
2020/08/29 Javascript
解决vant title-active-color与title-inactive-color不生效问题
2020/11/03 Javascript
python之super的使用小结
2018/08/13 Python
一篇文章搞懂Python的类与对象名称空间
2018/12/10 Python
浅谈python requests 的put, post 请求参数的问题
2019/01/02 Python
python3+selenium自动化测试框架详解
2019/03/17 Python
使用python 将图片复制到系统剪贴中
2019/12/13 Python
150行python代码实现贪吃蛇游戏
2020/04/24 Python
python查询MySQL将数据写入Excel
2020/10/29 Python
Django中template for如何使用方法
2021/01/31 Python
解决img标签上下出现间隙的方法
2016/12/14 HTML / CSS
Interrail法国:乘火车探索欧洲,最受欢迎的欧洲铁路通票
2019/08/27 全球购物
个人简历自我评价八例
2013/10/31 职场文书
迅雷Cued工作心得体会
2014/01/27 职场文书
村党支部书记个人对照材料汇报
2014/10/26 职场文书
教师党的群众路线学习心得体会
2014/11/04 职场文书
电影雨中的树观后感
2015/06/15 职场文书
Vue+Element UI实现概要小弹窗的全过程
2021/05/30 Vue.js
十大公认最好看的动漫:《咒术回战》在榜,《钢之炼金术师》第一
2022/03/18 日漫
Oracle配置dblink访问PostgreSQL的操作方法
2022/03/21 PostgreSQL