web开发Django+vue3

news/2024/11/6 5:04:01 标签: django, python, 后端

返回验证码图片

后端:返回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前端将二进制流文件显示

# 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的全局变量使用

// 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属性进行显示


http://www.niftyadmin.cn/n/5740196.html

相关文章

[spark面试]spark与mapreduce的区别---在DAG方面

1、spark中的task是以线程实现的&#xff0c;而mapreduce中是以进程实现的。 进程的频繁启动和停止会增加资源的消耗。 2、spark中支持DAG&#xff0c;而mapreduce不支持DAG DAG的使用&#xff1a;为什么支持DAG会更加高效 1&#xff09;、在DAG图中&#xff0c;会将一个job…

Linux 服务器使用指南:从入门到登录

&#x1f31f;快来参与讨论&#x1f4ac;&#xff0c;点赞&#x1f44d;、收藏⭐、分享&#x1f4e4;&#xff0c;共创活力社区。 &#x1f31f; &#x1f6a9;博主致力于用通俗易懂且不失专业性的文字&#xff0c;讲解计算机领域那些看似枯燥的知识点&#x1f6a9; 目录 一…

docker-ce-stable‘ 下载元数据失败 : Cannot download repomd.xml: Cannot download

看起来你在尝试安装 containerd.io-1.6.32 时遇到了问题&#xff0c;因为 docker-ce-stable 仓库的元数据下载失败。以下是一些可能的解决方案&#xff1a; 1. 检查仓库配置 确保你的 /etc/yum.repos.d/ 目录下的 docker-ce.repo 文件配置正确。你可以尝试手动编辑该文件&…

sqlalchemy连接mysql数据库

create_engine() 是 SQLAlchemy 中用于创建数据库连接的函数&#xff0c;它接受多个参数来配置连接池、日志输出等方面。你提到的 create_engine(DATABASE_URI, echoTrue, pool_size5, max_overflow2, pool_timeout30) 中的各个参数的含义如下&#xff1a; 1. DATABASE_URI 意…

【Windows修改Docker Desktop(WSL2)内存分配大小】

记录一下遇到使用Docker Desktop占用内存居高不下的问题 自从使用了Docker Desktop&#xff0c;电脑基本每天都需要重启&#xff0c;内存完全不够用&#xff0c;从16g扩展到24&#xff0c;然后到40G&#xff0c;还是不够用&#xff1b;打开Docker Desktop 运行时间一长&#x…

苹果iOS 18.4将允许欧盟地区的iPhone用户设置默认地图和翻译应用

在一份最新文件中&#xff0c;苹果概述了其为遵守欧盟数字市场法案所采取的措施&#xff0c;并透露将允许欧盟的 iPhone 和 iPad 用户从"2025 年春季"开始设置默认导航和翻译应用程序。 这一时间表表明&#xff0c;这些选项将在 iOS 18.4 和 iPadOS 18.4 中添加&…

docker对nginx.conf进行修改后页面无变化或页面报错

可能是因为没有重启nginx容器 可以执行 docker restart nginx 重启nginx试试 引入了其他的配置文件 本人安装的是docker默认的nginx&#xff0c;自带了一个default.conf的配置文件&#xff0c;并且在nginx.conf中还引入了这个文件&#xff0c;后面我还对nginx.conf添加了一个…

1-磁盘建立空闲分区

学习目标&#xff1a; 掌握磁盘分区的基本知识和操作技能&#xff0c;能够独立创建和管理磁盘空闲分区&#xff0c;以优化存储空间和提高系统性能&#xff0c;为后续的系统安装和数据管理打下基础。 学习内容&#xff1a; 1 选择一个适合的磁盘分区软件。推荐DiskGenius、Par…