使用Django+Vue编写一个文件上传器
作者:Cerelise_wong
前言
本教程中,我将会使用Django和Vue创建一个支持多文件上传的文件上传器。您可以在单个文件和多个文件上传之间选择在应用中进行上传操作。因此在这里您可以在本教程中我们将要构建的内容:
在完成上传操作以后,您可以在项目文件下找到上传的文件,而且它们按照年月日进行了分类:
同名文字的处理:Django会对同名文件进行重命名处理,非常方便
这看上去很不错。现在让我们开始编码吧!
Django部分
构建Django项目
(可选)创建项目虚拟环境
其实使用本机的全局环境也是可以的,看个人喜好。
python -m venv env
激活虚拟环境
env\Scripts\activate
退出虚拟环境命令--deactivate
安装Django及其他项目依赖
pip install django,django-cors-headers
创建Django app
python manage.py startapp document
完成上述操作后,项目目录如下:
配置settings.py
添加document应用到INSTALL_APPS
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'document' ]
配置媒体路径,指定上传文件的存放位置
MEDIA_URL = '/media/' MEDIA_ROOT = BASE_DIR / 'media'
构建document应用
创建模型(models.py)
进入document
文件夹,为文件上传创建数据库模型
from django.db import models class Document(models.Model): document = models.FileField(upload_to='uploads/%Y/%m/%d') def __str__(self): return str(self.pk)
upload_to
文件存放位置:基于MEDIA_ROOT
的起始路径。这里的uploads/
指文件将要存放在media
目录下新建的uploads
文件夹,可往下递推。
完成数据库模型的设置后,转到终端将设置写入到数据库
python manage.py makemigrations python manage.py migrate
创建表单(forms.py)
我们可以新建一个新的表单用于提交上传文件到数据库
from django import forms from .models import Document class UploadForm(forms.ModelForm): class Meta: model = Document fields = ('document', ) def save_multiple(self, documents): for file in documents: document = Document(document=file) document.save()
编写接口(views.py)
编写views.py
,添加multiply_upload
接口,通过JsonResponse返回上传状态
from django.middleware.csrf import get_token from django.http import JsonResponse from django.views.decorators.csrf import csrf_exempt from .forms import UploadForm @csrf_exempt def multiply_upload(request): if request.FILES: form = UploadForm(request.FILES) if form.is_valid(): documents = request.FILES.getlist('document') form.save_multiple(documents) return JsonResponse({'message': 'success'})
添加路由(urls.py)
在app目录下添加视图路由
from django.urls import path from . import views urlpatterns = [ path('multiply-upload/', views.multiply_upload, name='multiply_upload') ]
在core目录下添加api路由
from django.contrib import admin from django.urls import path, include from django.conf import settings from django.conf.urls.static import static # 完整路径地址示例:http://example.com/api/multiply-upload/ urlpatterns = [ path('admin/', admin.site.urls), path('api/', include('document.urls')), ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
添加 static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) 是为了能够在服务端地址上访问
media
内的文件
至此,django后端构建完成,接下来编写Vue代码
Vue部分
这里主要编写前后端的数据通信,使用axios
发送http请求
function multipleFilesUpload() { const formData = new FormData() files.value.forEach((file) => { formData.append('document', file) }) axios .post('http://127.0.0.1:8000/api/multiply-upload/', formData, { headers: { 'Content-Type': 'multipart/form-data', }, }) .then((res) => console.log(res.data.message)) .catch((error) => { console.log('error :>> ', error) }) files.value = '' }
添加一个按钮以发送上传请求
<button class="my-5 border border-gray-400 rounded-lg px-4 py-2 hover:bg-sky-400 hover:text-white duration-200" @click="multipleFilesUpload"> 上传 </button>
处理跨域问题
通过django-cors-headers处理跨域请求(settings.py)
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'corsheaders', 'document' ]
添加中间件corsheaders.middleware.CorsMiddleware
注意:跨域中间件要添加在
django.middleware.common.CommonMiddleware
之前
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ]
配置跨域规则
CORS_ALLOWED_ORIGINS = ["http://localhost:5173"] # 前端地址 CORS_ALLOW_METHODS = [ "DELETE", "GET", "OPTIONS", "PATCH", "POST", "PUT", ] CORS_ALLOW_HEADERS = [ "accept", "accept-encoding", "authorization", "content-type", "dnt", "origin", "user-agent", "x-csrftoken", "x-requested-with", ]
设置完成后,可以启动项目验证功能是否正常运行。
启动项目
前端
在前端工程文件目录下运行:
npm run dev
github仓库的项目使用的是yarn dev
,使用yarn还是npm看个人喜好
后端
先迁移数据库(克隆项目的情况下)
python manage.py makemigrations python manage.py migrate
启动项目
python manage.py runserver
测试效果
这看上去很酷,但是很多方面需要扩展,比如进度条,显示上传状态...不过最基本的功能已经实现,后面同学们可以根据自己的需要扩展功能。
写在最后
这个后端示例并不是一个很好的示范,前后端分离模式下前端发送请求至django后端需要解决跨域问题和csrf跨站请求保护,跨域可以通过django-cors-headers
解决,而csrf跨站请求需要csrfToken
和csrfCookie
双重认证,由于笔者的水平有限,只能实现前端从后端请求csrftoken然后将其添加到请求头中,但是没有cookie仍是不能实现上传。最后在后端通过django提供的装饰器,为特定的视图加上装饰器进行csrf的豁免。
#FBV:直接在函数上方加装饰器 @csrf_exempt 即可不验证csrf from django.views.decorators.csrf import csrf_exempt @csrf_exempt def multiply_upload(request): # 处理逻辑
如果有对这块熟悉的朋友可以在评论区指导一下,我先在这里感谢各位了!
后面会更新使用rest_framework
实现的类视图的多文件上传接口,我个人觉得使用DRF写接口要方便得多,作为一个前端开发者,使用Django作为后端开发语言确实要得心应手一些。
再次感谢您的阅读!
源码参考:github
以上就是使用Django+Vue编写一个文件上传器的详细内容,更多关于Django+Vue文件上传器的资料请关注脚本之家其它相关文章!