django+vue实现前端文件上传以及后端文件处理返回

目录

创建vue、django项目

创建vue项目

命令创建

项目目录

文件初始化

创建django项目

django+vue运行

vue项目打包

django创建apps

配置django项目

vue页面路径修正

实现前后端图片文件的交互

前端vue

后端django


创建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的检验,但是在正常项目中此项一般不做使用,容易造成跨域的问题。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值