目录
创建vue、django项目
创建vue项目
命令创建
进入create_vue目录,使用cmd打开终端,输入vue应用创建命令(fileUpload是项目名字、若出现package-name和project-name一致即可)
npm create vue@latest
cd fileUpload
npm install
npm run dev
若项目能出现以下画面则创建成功
项目目录
将src文件夹中其他无关文件删除,最终的文件目录如下(其他如node_module、dist、等无关文件夹在此处已省略,我们只需要关心src目录下的文件)。
└─src
│ App.vue
│ main.js
└─components
HelloWorld.vue
文件初始化
HelloWorld.vue内容
<script setup>
//此处写js相关代码,参考vue.js官网
</script>
<template>
<!-- 此处写html页面结构代码 -->
<h1>
this is helloworld
</h1>
</template>
<style scoped>
/* 此处写css相关代码 */
</style>
App.vue内容
<script setup>
import HelloWorld from './components/HelloWorld.vue'
</script>
<template>
<HelloWorld></HelloWorld>
</template>
<style scoped>
</style>
main.js内容
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
到此为止vue项目已经创建完毕
创建django项目
可以使用windows命令行创建django项目,在这里为了方便我们使用pycharm帮助我们创建django项目,Application为空时默认使用父文件夹的文件名作为django项目的名字,输入Application name(runapps)后pycharm会默认创建一个runapps应用。
创建成功后我们在settings.py文件中加入import os即可运行django项目,出现如下画面表示django项目创建成功。
django+vue运行
vue项目打包
进入vue项目目录下执行以下命令将vue项目打包成dist文件夹,这个dist文件夹即为我们前端项目的打包文件
npm run build
django创建apps
进入django项目,终端运行命令创建django的app,其中runapps为app的名称
python manage.py startapp runapps
配置django项目
执行完毕后将program_django下面的urls.py复制到runapps目录下,修改program_django目录下的urls.py,此处url为项目路由,配置域名到应用的映射,即项目路由
program_django/urls.py
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
path('admin/', admin.site.urls),
path("",include("runapps.urls"))
]
在我们创建的runapps的应用下在view.py文件里面配置视图,此处为后端应用的页面逻辑处理的地方、在urls.py文件下配置应用路由,即子域名到视图函数的映射。
runapps/urls.py
from django.urls import path
from django.views.generic import TemplateView
urlpatterns = [
path('', TemplateView.as_view(template_name='index.html')),
]
此处我们需要再django项目中创建文件夹放vue项目,创建web文件夹,将前端项目放入web文件夹中,并且在前端项目中创建static文件夹作为前端网页的静态资源,此时我们的项目结构如下所示
│ db.sqlite3
│ manage.py
├─program_django
│ │ asgi.py
│ │ settings.py
│ │ urls.py
│ └─wsgi.py
├─runapps
│ │ admin.py
│ │ apps.py
│ │ models.py
│ │ tests.py
│ │ urls.py
│ └─ views.py
└─web
└─dist
│ favicon.ico
│ index.html
└─static
│assets
└─ index-c7d3e1a4.js
进入program_django/setting.py文件中配置django项目按如下修改。
TEMPLATES=[{
'DIRS': []
}]
// 将以上内容修改为
TEMPLATES=[{
'DIRS': [BASE_DIR/"web/dist"]
}]
//添加如下设置
APPEND_SLASH=False
STATICFILES_DIRS=[
os.path.join(BASE_DIR,'web/dist/static')
]
vue页面路径修正
进入web/dist/index.html
将script标签和link标签中src的路径修正为“static/assets/index-xxx.js”,js名字每个项目不同,只要路径无误即可。
此时运行django项目即可进入我们前端开发的项目了。
实现前后端图片文件的交互
前端vue
我们使用vue创建好项目后写入相应的html页面结构和对应的css样式代码,其中:src表示动态绑定变量作为src的值,@click=“submit”表示绑定鼠标点击事件为submit函数,@change=“filechange”表示当选中的文件发生变化事件调用的函数。
HelloWorld.vue
<template>
<div class="mainScript">
<img :src="imageBase64" id="showOrigin"/>
<img :src="imageoperated" id="showFinished"/>
</div>
<div class="bottom">
<input type="file" name="file" id="loadFile" @change="fileChange">
<button class="bottomClick" @click="submit">运行模型</button>
<button class="bottomClick">清除图片</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
import axios from 'axios'
let imageBase64=ref("12")
let imageoperated=ref("")
let _fileobj
function fileChange(event){
let file=event.target.files[0]
//获取新选中的文件
_fileobj=file
let blobfile=new Blob([file])
let fr=new FileReader()
fr.readAsDataURL(blobfile)
fr.onloadend = function(event){
imageBase64.value=fr.result
}
//使用filereader读取图片文件数据并放入页面做预览
}
async function submit(){
// 异步将filedata转换为formdata
let _formData=new FormData();
//创建FormData对象准备给后端提交数据
_formData.append("file",_fileobj)
//使用axios向后端请求数据并传入用户选中的图片
axios({
method:'post',
//请求的方式
url:'/loadfile/',
//此处为请求的子域名后续需要在后端进行配置
responseType:'arraybuffer',
data:_formData
//传入后端的数据
}).then(function(res){
//二进制转buffer
let binary=''
let bytes=new Uint8Array(res.data)
//接收后端传回的数据
let length=bytes.length
for(let i=0;i<length;i++){
binary+=String.fromCharCode(bytes[i])
}
imageoperated.value='data:image/jpeg;base64,' + window.btoa(binary)
//将数据转为字符串数据用作图片src的绑定
})
}
</script>
<style scoped>
.bottom{
background-color: aqua;
position: absolute;
bottom: 0px;
height: 50px;
width: 100%;
text-align: center;
}
.bottomClick{
margin-left: 150px;
height: 40px;
top: 5px;
margin-top: 5px;
font-size: 20px;
width: 200px;
}
#loadFile{
margin-left: 150px;
height: 40px;
margin-top: 5px;
font-size: 20px;
width: 400px;
}
img{
text-align: center;
height: auto;
width: 50%;
}
.mainScript{
height: auto;
width: 100%;
}
</style>
在js中若axios报错则需要进行安装axios,在前端项目下运行npm install axios即可安装完成,整个项目思路为获取用户选中的文件,使用全局变量进行存储,此处应该进行文件类型的校验,以便于图片预览,否则将无法展示图片。当用户点击提交时使用axios的post请求携带文件数据向后端请求处理后的图片。url表示向后端请求的子域名路由。
后端django
django项目中我们仅需要修改两个文件,runapps/views.py和runapps/urls.py
views.py
from django.http.response import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from PIL import Image
import io
def get_django_img(origin_image):
img=Image.open(origin_image)
# 创建字节流管道对象
img_bytes=io.BytesIO()
img.convert("RGB")
img.save(img_bytes,format="png")
# 在字节流中获取二进制数据
return img_bytes.getvalue()
@csrf_exempt
def loadfile(request):
file=request.FILES.get("file")
# 获取表单中的文件
file_list=request.FILES.items()
if not file_list:
print("文件上传失败")
else:
img_bytes=get_django_img(file)
return HttpResponse(img_bytes,content_type="image/png")
urls.py
from django.urls import path
from django.views.generic import TemplateView
from runapps import views
urlpatterns = [
path('', TemplateView.as_view(template_name='index.html')),
path("loadfile/",views.loadfile)
]
urls.py中path的loadfile为前端请求的urls子域名,可修改但是需要二者对应,views.py中@csrf_exempt表示注释不需要csrf_token的检验,但是在正常项目中此项一般不做使用,容易造成跨域的问题。