使用Django+Vue編寫一個(gè)文件上傳器
前言
本教程中,我將會(huì)使用Django和Vue創(chuàng)建一個(gè)支持多文件上傳的文件上傳器。您可以在單個(gè)文件和多個(gè)文件上傳之間選擇在應(yīng)用中進(jìn)行上傳操作。因此在這里您可以在本教程中我們將要構(gòu)建的內(nèi)容:
在完成上傳操作以后,您可以在項(xiàng)目文件下找到上傳的文件,而且它們按照年月日進(jìn)行了分類:
同名文字的處理:Django會(huì)對(duì)同名文件進(jìn)行重命名處理,非常方便
這看上去很不錯(cuò)。現(xiàn)在讓我們開始編碼吧!
Django部分
構(gòu)建Django項(xiàng)目
(可選)創(chuàng)建項(xiàng)目虛擬環(huán)境
其實(shí)使用本機(jī)的全局環(huán)境也是可以的,看個(gè)人喜好。
python -m venv env
激活虛擬環(huán)境
env\Scripts\activate
退出虛擬環(huán)境命令--deactivate
安裝Django及其他項(xiàng)目依賴
pip install django,django-cors-headers
創(chuàng)建Django app
python manage.py startapp document
完成上述操作后,項(xiàng)目目錄如下:
配置settings.py
添加document應(yīng)用到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'
構(gòu)建document應(yīng)用
創(chuàng)建模型(models.py)
進(jìn)入document
文件夾,為文件上傳創(chuàng)建數(shù)據(jù)庫(kù)模型
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
文件夾,可往下遞推。
完成數(shù)據(jù)庫(kù)模型的設(shè)置后,轉(zhuǎn)到終端將設(shè)置寫入到數(shù)據(jù)庫(kù)
python manage.py makemigrations python manage.py migrate
創(chuàng)建表單(forms.py)
我們可以新建一個(gè)新的表單用于提交上傳文件到數(shù)據(jù)庫(kù)
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
接口,通過(guò)JsonResponse返回上傳狀態(tài)
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) 是為了能夠在服務(wù)端地址上訪問(wèn)
media
內(nèi)的文件
至此,django后端構(gòu)建完成,接下來(lái)編寫Vue代碼
Vue部分
這里主要編寫前后端的數(shù)據(jù)通信,使用axios
發(fā)送http請(qǐng)求
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 = '' }
添加一個(gè)按鈕以發(fā)送上傳請(qǐng)求
<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>
處理跨域問(wèn)題
通過(guò)django-cors-headers處理跨域請(qǐng)求(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', ]
配置跨域規(guī)則
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", ]
設(shè)置完成后,可以啟動(dòng)項(xiàng)目驗(yàn)證功能是否正常運(yùn)行。
啟動(dòng)項(xiàng)目
前端
在前端工程文件目錄下運(yùn)行:
npm run dev
github倉(cāng)庫(kù)的項(xiàng)目使用的是yarn dev
,使用yarn還是npm看個(gè)人喜好
后端
先遷移數(shù)據(jù)庫(kù)(克隆項(xiàng)目的情況下)
python manage.py makemigrations python manage.py migrate
啟動(dòng)項(xiàng)目
python manage.py runserver
測(cè)試效果
這看上去很酷,但是很多方面需要擴(kuò)展,比如進(jìn)度條,顯示上傳狀態(tài)...不過(guò)最基本的功能已經(jīng)實(shí)現(xiàn),后面同學(xué)們可以根據(jù)自己的需要擴(kuò)展功能。
寫在最后
這個(gè)后端示例并不是一個(gè)很好的示范,前后端分離模式下前端發(fā)送請(qǐng)求至django后端需要解決跨域問(wèn)題和csrf跨站請(qǐng)求保護(hù),跨域可以通過(guò)django-cors-headers
解決,而csrf跨站請(qǐng)求需要csrfToken
和csrfCookie
雙重認(rèn)證,由于筆者的水平有限,只能實(shí)現(xiàn)前端從后端請(qǐng)求csrftoken然后將其添加到請(qǐng)求頭中,但是沒(méi)有cookie仍是不能實(shí)現(xiàn)上傳。最后在后端通過(guò)django提供的裝飾器,為特定的視圖加上裝飾器進(jìn)行csrf的豁免。
#FBV:直接在函數(shù)上方加裝飾器 @csrf_exempt 即可不驗(yàn)證csrf from django.views.decorators.csrf import csrf_exempt @csrf_exempt def multiply_upload(request): # 處理邏輯
如果有對(duì)這塊熟悉的朋友可以在評(píng)論區(qū)指導(dǎo)一下,我先在這里感謝各位了!
后面會(huì)更新使用rest_framework
實(shí)現(xiàn)的類視圖的多文件上傳接口,我個(gè)人覺(jué)得使用DRF寫接口要方便得多,作為一個(gè)前端開發(fā)者,使用Django作為后端開發(fā)語(yǔ)言確實(shí)要得心應(yīng)手一些。
再次感謝您的閱讀!
源碼參考:github
以上就是使用Django+Vue編寫一個(gè)文件上傳器的詳細(xì)內(nèi)容,更多關(guān)于Django+Vue文件上傳器的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python中kmeans聚類實(shí)現(xiàn)代碼
這篇文章主要為大家詳細(xì)介紹了python中kmeans聚類的實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-02-02Python腳本利用adb進(jìn)行手機(jī)控制的方法
這篇文章主要介紹了Python腳本利用adb進(jìn)行手機(jī)控制的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07Windows上使用virtualenv搭建Python+Flask開發(fā)環(huán)境
在自己本機(jī)的開發(fā)環(huán)境下,我們完全可以使用virtualenv來(lái)hold住多個(gè)Python環(huán)境,這樣就可以留出一個(gè)專門服役于Flask框架,哈哈,這里我們就來(lái)看看如何在Windows系統(tǒng)上使用virtualenv搭建Python+Flask開發(fā)環(huán)境2016-06-06Python練習(xí)之操作SQLite數(shù)據(jù)庫(kù)
這篇文章主要介紹了Python練習(xí)之操作SQLite數(shù)據(jù)庫(kù),主要通過(guò)三個(gè)問(wèn)題如何創(chuàng)建SQLite數(shù)據(jù)庫(kù)?如何向SQLite表中插入數(shù)據(jù)?如何查詢SQLite表中的數(shù)據(jù)?展開文章主題詳情,需要的朋友可以參考一下2022-06-06python中partial()基礎(chǔ)用法說(shuō)明
這篇文章主要給大家介紹了關(guān)于python中partial()基礎(chǔ)用法的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用python具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧2018-12-12python修改注冊(cè)表終止360進(jìn)程實(shí)例
這篇文章主要介紹了python修改注冊(cè)表終止360進(jìn)程實(shí)例,是非常實(shí)用的進(jìn)程操作技巧,需要的朋友可以參考下2014-10-10python ftp 按目錄結(jié)構(gòu)上傳下載的實(shí)現(xiàn)代碼
這篇文章主要介紹了python ftp 按目錄結(jié)構(gòu)上傳下載的實(shí)現(xiàn)代碼,需要的朋友可以參考下2018-09-09Python2和Python3中@abstractmethod使用方法
這篇文章主要介紹了Python2和Python3中@abstractmethod使用方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-02-02