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中使用动态变量名的方法
May 06 Python
python学习 流程控制语句详解
Jun 01 Python
Python设计足球联赛赛程表程序的思路与简单实现示例
Jun 28 Python
python爬虫面试宝典(常见问题)
Mar 02 Python
windows下cx_Freeze生成Python可执行程序的详细步骤
Oct 09 Python
Python分析彩票记录并预测中奖号码过程详解
Jul 09 Python
python3使用print打印带颜色的字符串代码实例
Aug 22 Python
python图形绘制奥运五环实例讲解
Sep 14 Python
numpy中三维数组中加入元素后的位置详解
Nov 28 Python
Python 音频生成器的实现示例
Dec 24 Python
深入浅析python 中的self和cls的区别
Jun 20 Python
详解Golang如何实现支持随机删除元素的堆
Sep 23 Python
python3 删除所有自定义变量的操作
Apr 08 #Python
pytorch显存一直变大的解决方案
Apr 08 #Python
Python文件的操作示例的详细讲解
Django展示可视化图表的多种方式
python tkinter模块的简单使用
python如何在word中存储本地图片
python 下载文件的几种方式分享
Apr 07 #Python
You might like
十大催泪虐心动漫,你能坚持看到第几部?
2020/03/04 日漫
php error_log 函数的使用
2009/04/13 PHP
php实现的一个简单json rpc框架实例
2015/03/30 PHP
PHP实现发送邮件的方法(基于简单邮件发送类)
2015/12/17 PHP
CI框架表单验证实例详解
2016/11/21 PHP
PHP 500报错的快速解决方法
2016/12/14 PHP
PHP微信H5支付开发实例
2018/07/25 PHP
PHP设计模式之观察者模式定义与用法分析
2019/04/04 PHP
Javascript调用XML制作连动下拉列表框
2006/06/25 Javascript
javascript 浏览器检测代码精简版
2010/03/04 Javascript
jquery png 透明解决方案(推荐)
2010/08/21 Javascript
autoIMG 基于jquery的图片自适应插件代码
2011/03/12 Javascript
在js中判断checkboxlist(.net控件客户端id)是否有选中
2013/04/11 Javascript
基于NodeJS的前后端分离的思考与实践(六)Nginx + Node.js + Java 的软件栈部署实践
2014/09/26 NodeJs
node.js中的fs.rename方法使用说明
2014/12/16 Javascript
Extjs表单输入框异步校验的插件实现方法
2017/03/20 Javascript
Vue中保存用户登录状态实例代码
2017/06/07 Javascript
微信小程序实现动态显示和隐藏某个控件功能示例
2018/12/14 Javascript
JS温故而知新之变量提升和时间死区
2019/01/27 Javascript
vue-cli3添加模式配置多环境变量的方法
2019/06/05 Javascript
layui多图上传实现删除功能的例子
2019/09/23 Javascript
35个Python编程小技巧
2014/04/01 Python
Python中super关键字用法实例分析
2015/05/28 Python
Python设置Socket代理及实现远程摄像头控制的例子
2015/11/13 Python
Python绘制3D图形
2018/05/03 Python
解决Python 使用h5py加载文件,看不到keys()的问题
2019/02/08 Python
Django外键(ForeignKey)操作以及related_name的作用详解
2019/07/29 Python
canvas粒子动画背景的实现示例
2018/09/03 HTML / CSS
保护环境建议书
2014/03/12 职场文书
中学生励志演讲稿
2014/04/26 职场文书
安全横幅标语
2014/06/09 职场文书
法学专业毕业生自荐信
2014/06/11 职场文书
最美孝心少年事迹材料
2014/08/15 职场文书
搞笑的爱情检讨书
2014/10/01 职场文书
实习单位推荐信
2015/03/27 职场文书
mysql全面解析json/数组
2022/07/07 MySQL