web开发Django+vue3

返回验证码图片

后端:返回Http对象,content_type设置为image

python 复制代码
# 验证码测试视图函数
def get_captcha(request):
    img, code = generate_captcha()  # 生成验证码
    request.session['captcha_code'] = code  # 将验证码保存到session中
    buf = BytesIO()  # 创建一个BytesIO对象,用于存储验证码图片
    img.save(buf, 'png')  # 将验证码图片保存到BytesIO对象中
    return HttpResponse(buf.getvalue(),content_type="image/png")  # 返回验证码图片的二进制数据

前端:设置imageUrl变量,img自动访问资源

python 复制代码
<img :src="imageUrl" v-on:click=imgSrc(this) alt="验证码图片" style="width: 100px; margin-left: 40px;" />

但是没办法点击刷新验证码

重新绑定函数完成。

@click="imgSrc"



const imgSrc = () => {
    imageUrl.value = imageUrl.value + '?' + new Date().getTime()
    api.get_session().then((res) => {
        console.log(res)
    })
}

前端请求cookie丢失

原文链接:Django+vue 解决cookie跨域不携带问题(本地)以及上线后 - 春游去动物园 - 博客园

1排除了跨域问题,后端已经解决了跨域

后端通过

pip install django-cors-headers

sessting.py设置

SESSION_EXPIRE_AT_BROWSER_CLOSE = True  # 会话cookie可以在用户浏览器中保持有效期。 False---session 在一段时间不活动后过期。True:关闭浏览器,则Cookie失效。
SESSION_COOKIE_SAMESITE = None
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
CSRF_COOKIE_SAMESITE = None
CSRF_COOKIE_SECURE = False
CORS_ALLOW_METHODS = (
    'DELETE',
    'GET',
    'OPTIONS',
    'PATCH',
    'POST',
    'PUT',
    'VIEW',
)

CORS_ALLOW_HEADERS = (
    'XMLHttpRequest',
    'X_FILENAME',
    'accept-encoding',
    'authorization',
    'content-type',
    'dnt',
    'origin',
    'user-agent',
    'x-csrftoken',
    'x-requested-with',
    'Pragma',
    'Cookie',
)

解决了跨域问题

前端通过代理域名,二次封装axios请求完成

vue.config.js

devServer: {  //开启代理服务器
    proxy:{
      "/api": {  // /api是自行设置的请求前缀,按照这个来匹配请求,有这个字段的请求,就会走到代理来。
          target: "http://127.0.0.1:8081", // 需要代理的域名,目标域名,会替换掉匹配字段之前的路径
           ws: false, // 是否启用websockets
          changeOrigin: true, //是否跨域
          pathRewrite: {  //重写匹配的字段,如果不需要放在请求路径上,可以重写为""
              "^/api": ""
          }
        },
    }
  },

request.js

const instance = axios.create({
  timeout:5000,
  baseURL:'/api', // 设置通用请求的地址前缀
  withCredentials : true
})

可以传递cookie。

但是session无法获取,大概猜到原因,依然是跨域问题,在vue的api封装解决了跨域,但是session的设置是根据img的src路径直接访问,依然存在跨域问题,所以重点在于解决前端使用跨域解决获取验证码图片的操作

很难受,没怎么用心学VUE,在前端访问后端接口的时候后端传回图片的二进制数据流,但是前端一直无法显示,cors跨域问题已经解决,明白只要通过二次封装的axios请求就可以通过后端设置session。但是前端一直无法显示,尝试了无数方法,最后发现我的responetype设置到别的接口了,难怪一直没生效

vue3前端将二进制流文件显示

html 复制代码
# index.js文件中请求函数   
get_capt() {
    return axios.get(base.baseUrl + base.captcha ,{responseType: 'blob'})
   },


//使用的时候
// 生成验证码图片
const imgSrc = () => {
    api.get_capt().then((res) => {
        console.log(res)
        const blob = new Blob([res.data]);
		let url = window.URL.createObjectURL(blob); //根据返回的流文件创建url;url指向流
        imageUrl.value = url; // 创建一个指向 blob 对象的 URL
        console.log(imageUrl.value)
    })
}

登录设置cookie状态

前端访问登录页面,登录后,后端向前端设置cookie。

前端直接访问主页面,后端通过cookie判断时候存在登录状态的cookie,如果没有就返回信息,让前端跳转到登录页面。如果有的话就根据cookie返回登录的用户信息


菜单部分设置采用后端传递前端的方式

数据库设计t_meau表中设计为自关联表,通过后端序列化后进行返回给前端,前端读取页面并显示

自关联序列化序列化,没招数了,多表关联都能用,自关联只能学着写了。自己摸索的

python 复制代码
class Children2MeausSerializer(serializers.ModelSerializer):
    class Meta:
        model = meaus
        fields = ['id', 'name', 'level', 'path']

class ChildrenMeausSerializer(serializers.ModelSerializer):
    children = Children2MeausSerializer(many=True, read_only=True)
    class Meta:
        model = meaus
        fields = ['id', 'name', 'level', 'path', 'children']

class MeausSerializer(serializers.ModelSerializer):
    # 通过related_name='children'指定子级数据的反向查询字段名为children
    children = ChildrenMeausSerializer(many=True, read_only=True)
    class Meta:
        model = meaus
        fields = ['id', 'name', 'level', 'path', 'children']

上传用户头像并更改

通过el-upload,先判断传递图片是否符合要求,之后对传递的图片进行处理,并且保存为全局变量(需要对整个用户信息进行更新)获取到了图片信息之后通过请求后端接口将用户图像的图片信息传递过去。从后端拿到图片的地址在返回给前端。后端通过接收到图片的信息后将图片的上传到七牛云中进行云端储存,并且将储存的云端地址保存到mysql数据库当中。后端返回的时候将数据库的地址返回给前端,前端接收到数据地址进行赋值给表单或者弹窗中的图片地址,从而显示出图片

vue3的全局变量使用

javascript 复制代码
// main.vue
const { proxy } = getCurrentInstance()
let user_img= proxy.$user_img



// main.js
const app = createApp(App)

app.config.globalProperties.$user_img = '用户的头像地址';

app.use(router).provide("$axios",axios).mount('#app')

重新捋一下

用户选择好图片之后,点击上传,发送上传请求给后端。后端接收到上传的文件流,将文件流发送到七牛云平台进行保存,返回一个图片的链接地址。后端将接收到的链接地址保存更新数据库并返回给前端页面进行展示。直接更改前端的src路径。

卡了我一天时间

解决方式:

通过element-plus的el-upload组件进行上传头像,起初认为action自动发送的请求会出现跨域问题,所以一直想要更新源码进行发送请求,最后实践得知不会出现跨域问题,因为我的后端需要cookie进行身份辨别,所以添加了:with-credentials="true"

<el-dialog class="avatarDialog" :showClose="false" center v-model="avatarDialogVisible" title="更新头像">
              <el-upload 
                ref="upload"
                class="avatar-uploader" 
                :show-file-list="false" 
                action='http://localhost:8081/user/upload_img/'
                :with-credentials="true"   
                :on-success="handleAvatarSuccess"
                :before-upload="beforeAvatarUpload"    
                :auto-upload = 'true'
                >
                <img v-if="imageUrl" :src="imageUrl" class="avatar" />
                <el-icon v-else class="avatar-uploader-icon">
                  <Plus />
                </el-icon>
              </el-upload>
              <template #footer>
                <span class="dialog-footer">
                  <el-button @click="file_out">关闭</el-button>
                </span>
              </template>
            </el-dialog>

后端就可以接收到前端发送的请求

python 复制代码
@csrf_exempt
def upload_img(request):
    if request.method == 'POST':
        try:
            user_id = request.COOKIES.get('user_id')
            user = Users.objects.get(pk=user_id)
        except KeyError:
            return JsonResponse({"data":False,"msg":"登录过期,请重新登录"}, status=200)
        # json_data = json.loads(request.body)
        user_img = request.FILES['file'].file  # 获取用户上传的头像图片文件流
        file_name = upload_file(settings.AK, settings.SK, user_img)
        user.img = f'{settings.BUCKET_URL}/{file_name}'
        user.save()  # 将头像地址保存到数据库中
        print(f'文件地址:{settings.BUCKET_URL}/{file_name}')
        return JsonResponse({'data':'调用了接口',"user_img":user.img},status=200)

通过封装好的upload_file函数,将文件流上传到七牛云保存,并返回相应的地址,将地址更新到数据库当中,减少了数据库的储存量,返回给前端图片的路径地址。在通过scr属性进行显示

相关推荐
网易独家音乐人Mike Zhou21 分钟前
【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)
c语言·python·单片机·物联网·算法·嵌入式·iot
安静读书23 分钟前
Python解析视频FPS(帧率)、分辨率信息
python·opencv·音视频
小二·2 小时前
java基础面试题笔记(基础篇)
java·笔记·python
qq_17448285753 小时前
springboot基于微信小程序的旧衣回收系统的设计与实现
spring boot·后端·微信小程序
小喵要摸鱼3 小时前
Python 神经网络项目常用语法
python
锅包肉的九珍3 小时前
Scala的Array数组
开发语言·后端·scala
心仪悦悦3 小时前
Scala的Array(2)
开发语言·后端·scala
2401_882727574 小时前
BY组态-低代码web可视化组件
前端·后端·物联网·低代码·数学建模·前端框架
心仪悦悦4 小时前
Scala中的集合复习(1)
开发语言·后端·scala
一念之坤5 小时前
零基础学Python之数据结构 -- 01篇
数据结构·python