龙空技术网

Django搭建网络相册:批量上传文件

杜赛 219

前言:

此时你们对“html上传图片到数据库”大体比较珍视,兄弟们都需要分析一些“html上传图片到数据库”的相关资讯。那么小编同时在网上搜集了一些有关“html上传图片到数据库””的相关知识,希望姐妹们能喜欢,各位老铁们快快来学习一下吧!

虽然 Django 自带的后台已经能够上传图片了,但是默认只能单张上传。如果你照片比较多,实在是有点不方便。

现在让我们来试着实现批量上传图片的功能。

后端代码

上一章讲过 GET 和 POST 请求的区别。图片上传会修改服务器资源,因此应该用 POST 请求。

又鉴于 home() 视图函数已经肩负用户登录功能了,如果图片上传也在里面处理,会显得太乱。

因此在 /photo/views.py 里新写一个 upload() 视图,专门用来处理文件上传。

修改内容如下:

# /photo/views.py...from django.shortcuts import render, redirect...def upload(request):    if request.method == 'POST' and request.user.is_superuser:        images = request.FILES.getlist('images')        for i in images:            photo = Photo(image=i)            photo.save()    return redirect('home')

和前面的用户名、密码这类普通的字符串数据不同,图片这类二进制文件数据在 request 中有专门的地方存放,即 request.FILES 了。因为图片可以是批量上传,所以是类似列表的有序集合,用 .getlist('images') 将此集合取出。

接下来就简单了。迭代这个图片列表,将它们全部都保存到模型中。调用 photo.save() 方法将其存储到数据库。

最后,upload() 视图并没有返回响应体,而是跳转到 home() 视图去了,继续执行 home() 视图中的代码了。参数 'home' 对应之前章节定义的 path(... name='home') 这个路径名。

接着例行惯例,需要给视图函数配置一个路径:

# /photo/urls.py...from photo.views import home, upload...urlpatterns = [    ...    path('upload/', upload, name='upload'),]

接着去修改模板中的代码。

前端代码

上一章我们已经给上传文件预留了一个 “+” 号作为入口。

余下的工作就是将这个 “+” 号变成模态窗。

修改 header.html 模板:

<!-- /templates/header.html --><!-- 导航栏 --><nav class="navbar ...">    <div class="container">        ...        <!-- 修改登录模态窗链接 -->        {% if user.is_superuser %}            <ul class="navbar-nav">                <li class="nav-item">                <h2>                    <a                     class="nav-link active"                    href="#"                    data-bs-toggle="modal"                    data-bs-target="#upload"                    >                        +                    </a>                </h2>                </li>            </ul>        {% endif %}    </div></nav><!-- 模态窗相关代码 -->{% if user.is_superuser %}...<!-- 新增上传模态窗 --><div class="modal fade" id="upload">    <div class="modal-dialog">        <div class="modal-content">            <div class="modal-body">                <h5 class="modal-title">上传图片</h5>                <form action="{% url 'photo:upload' %}"                method="post"                enctype="multipart/form-data"                >                    {% csrf_token %}                    <div class="col py-2">                        <input                            class="form-control"                             type="file"                            id="images"                             name="images"                             multiple="multiple"                            accept="image/*"                        >                    </div>                    <button type="submit" class="btn btn-primary">提交</button>                </form>            </div>        </div>    </div></div>{% else %}...{% endif %}

"+" 号通过超链接,作为触发模态窗的按钮。之所以还是考虑用模态窗的形式,是因为上传表单的信息量太小,没必要做页面的跳转。

让我们仔细看看上传文件表单的构造。

首先看 <form ...> 标签里的东东:

action="{% url 'photo:upload' %}" 指定此表单提交的路径。再次注意看它是如何和 url 路径的名称对应的。method="post" 说明这是个 POST 请求的表单。enctype="multipart/form-data" 指定表单的编码方式(将文件以二进制上传),必须有它才能正常上传文件。

再看 <input ... > 标签里:

type="file" 表示这是个文件上传控件。name="images" 注意它要和后端代码的 .getlist('images') 的参数对应。multiple="multiple" 表示支持多文件上传。accept="image/*" 文件类型为图片。

欧了,测试。

测试

刷新页面,点击加号:

接下来就简单了,点击控件,随意选定多个图片,再点击提交按钮,图片就上传成功了。

总结

图片上传本身并不难,难的是对其进行安全的处理:

如何裁剪图片尺寸?如何限制图片类型?如何判断图片里是否带有病毒?如何确保用户没有上传奇怪的小电影截图?

个人相册还好说,操作资源就自己,不会瞎折腾。但如果你要开发论坛或平台,这些都是要好好考虑的。

另一个现实的问题是,云服务器资源是昂贵的,作为草根网站,你的服务器带宽根本支撑不起庞大的图片流量。用户会在你的站点卡得吐血。教程末尾章节将会解决这个问题,在此之前,下一章先聊聊分页。

点赞 or 吐槽?评论区和我聊!

标签: #html上传图片到数据库 #上传图片至数据库