【VUE】案例:商场会员管理系统
编写vue+dfr实现对会员进行基本增删改查
1. drf项目初始化
-
请求:
POST http://127/0.0.0.1:8000/api/auth/ {"username":"cqn", "password":"123"}
-
返回:
{"username":"cqn", "token":"fwjkfbj"}
-
创建项目
-
项目目录结构
1.1 安装并注册drf
- pip install djangorestframework
- settings.py
INSTALLED_APPS = [...'django.contrib.staticfiles','api.apps.ApiConfig','rest_framework', ]
1.2 创建数据库表并添加数据
- models.py
from django.db import modelsclass UserInfo(models.Model):username = models.CharField(verbose_name="用户名", max_length=64)password = models.CharField(verbose_name="密码", max_length=64)token = models.CharField(verbose_name="token", max_length=64, null=True, blank=True)
- makemigrations
- migrate
- 插入两条数据“root 123”,“cqn 123”
1.3 创建apiview文件
views/account.py
import uuid
from rest_framework import serializers
from rest_framework.views import APIView
from rest_framework.response import Response
from api import modelsclass AuthSerializer(serializers.Serializer):username = serializers.CharField(required=True)password = serializers.CharField(required=True)class AuthView(APIView):def post(self, request):# 1. 获取用户提交数据 request.data = {"username": "xxx", "password": "...}# 2. 表单校验ser = AuthSerializer(data=request.data)if not ser.is_valid():return Response({"code": 1000, "msg": "校验失败", "detail": ser.errors})# 3. 数据库校验user_object = models.UserInfo.objects.filter(**ser.data).first()if not user_object:return Response({"code": -1, "msg": "用户名或密码错误"})token = uuid.uuid4()user_object.token = tokenuser_object.save()# 4. 数据返回return Response({"code": 0,"data": {"id": user_object.id, "name": user_object.username, "token": user_object.token}})
1.4 添加url配置
urls.py
from django.urls import path
from api.views import accounturlpatterns = [path('api/auth/', account.AuthView.as_view()),
]
1.5 启动并验证
2. vue项目初始化
- 创建项目
- 项目目录
2.1 main.js注释全局样式
// import './assets/main.css'
2.2 App.vue
<script setup>
</script><template><RouterView />
</template><style scoped>
</style>
2.3 views
LoginView.vue
<template><div class="box"><p>用户名:<input type="text" placeholder="用户名" v-model="msg.username"></p><p>密码:<input type="text" placeholder="密码" v-model="msg.password"></p><p><button @click="doLogin">登录</button></p></div>
</template><script setup>
import {ref} from "vue";
import {useRouter} from "vue-router";
import {userInfoStore} from "@/stores/user.js";
import _axios from "@/plugins/axios.js";const msg = ref({username: "",password: ""
})
const router = useRouter()
const store = userInfoStore()const doLogin = function () {// 1、获取数据console.log(msg.value)// 2、发送网络请求_axios.get("/api/v1/course/category/free/?courseType=free").then((res) => {console.log(res.data)})// 3、本地存储用户信息(登录凭证)// localStorage.setItem("name", msg.value.username)let info = {id: 1, name: msg.value.username, token: "ddsafhsjdfkj"}store.doLogin(info)// 3、跳转到首页router.push({name: "mine"})
}</script><style scoped>
.box {width: 300px;margin: 100px auto;
}
</style>
AdminView.vue
<template><div class="page-header"><div class="container"><RouterLink to="/admin/mine">我的</RouterLink>|<RouterLink to="/admin/order">订单</RouterLink><div style="float:right;"><a>{{store.userName}}</a><a @click="doLogout">退出1</a></div></div></div><div class="container"><RouterView/></div>
</template><script setup>
import {useRouter} from "vue-router";
import {userInfoStore} from "@/stores/user.js";const router = useRouter()
const store = userInfoStore()function doLogout() {store.doLogout()router.push({name: "login"})
}
</script><style scoped>
body {margin: 0;
}.page-header {height: 48px;background-color: cornflowerblue;line-height: 48px;
}.page-header a {display: inline-block;padding: 0 10px;cursor: pointer;
}.container {width: 980px;margin: 0 auto;
}</style>
MineView.vue
<template><h1>Mine</h1>
</template><script setup>
</script><style scoped>
</style>
OrderView.vue
<template><h1>Order</h1>
</template><script setup>
</script><style scoped>
</style>
2.4 stores
user.js
import {ref, computed} from 'vue'
import {defineStore} from 'pinia'export const userInfoStore = defineStore('userInfo', () => {const userString = ref(localStorage.getItem("info"))const userDict = computed(() => userString.value ? JSON.parse(userString.value) : null)const userId = computed(() => userDict.value ? userDict.value.id : null)const userName = computed(() => userDict.value ? userDict.value.name : null)const userToken = computed(() => userDict.value ? userDict.value.token : null)function doLogin(info) {localStorage.setItem("info", JSON.stringify(info))userString.value = JSON.stringify(info)}function doLogout() {localStorage.clear()userString.value = null}return {userId, userName, userToken, doLogin, doLogout}
})
2.5 router
index.js
import { createRouter, createWebHistory } from 'vue-router'
import {userInfoStore} from "@/stores/user.js";const router = createRouter({history: createWebHistory(import.meta.env.BASE_URL),routes: [{path: '/login',name: 'login',component: () => import('../views/LoginView.vue')},{path: '/admin',name: 'admin',component: () => import('../views/AdminView.vue'),children: [{path: "",redirect: {name: "mine"}},{path: "mine",name: "mine",component: () => import('../views/MineView.vue')},{path: "order",name: "order",component: () => import('../views/OrderView.vue')}]}]
})
router.beforeEach(function (to,from,next) {// 1.访问登录页面,不需要登录就可以直接去查看if (to.name === "login") {next()return}// 2.检查用户登录状态,登录成功,继续往后走next();未登录,跳转至登录页面// let username = localStorage.getItem("name")const store = userInfoStore()if (!store.userId){next({name:"login"})return;}// 3.登录成功且获取到用户信息,继续向后访问next()
})export default router
2.6 plugins
axios.js
import axios from "axios";let config = {baseURL: "https://api.luffycity.com/",timeout: 20 * 1000
}const _axios = axios.create(config)_axios.interceptors.request.use(function (config){// console.log("请求前:", config)// 1. 去pinia中读取当前用户token// 2. 发送请求时携带tokenif(config.params){config.params["token"] = "djbfkjbdfkj"} else {config.params = {"token": "whejsabjdnfj"}}return config
})export default _axios
2.7 安装并启动应用
- sudo npm i
- sudo npm i axios
- sudo npm run dev
3、前端调用后端,代码配置
ajax.js
import axios from "axios";let config = {baseURL: "http://127.0.0.1:8000/",timeout: 20 * 1000
}const _axios = axios.create(config)_axios.interceptors.request.use(function (config){// console.log("请求前:", config)// 1. 去pinia中读取当前用户token// 2. 发送请求时携带token// if(config.params){// config.params["token"] = "djbfkjbdfkj"// } else {// config.params = {"token": "whejsabjdnfj"}// }return config
})export default _axios
LoginView.vue
<template><div class="box"><p>用户名:<input type="text" placeholder="用户名" v-model="msg.username"></p><p>密码:<input type="text" placeholder="密码" v-model="msg.password"></p><p><button @click="doLogin">登录</button></p></div>
</template><script setup>
import {ref} from "vue";
import {useRouter} from "vue-router";
import {userInfoStore} from "@/stores/user.js";
import _axios from "@/plugins/axios.js";const msg = ref({username: "",password: ""
})
const router = useRouter()
const store = userInfoStore()const doLogin = function () {// 1、获取数据console.log(msg.value)// 2、发送网络请求_axios.post("/api/auth/", msg.value).then((res) => {console.log(res.data)})// 3、本地存储用户信息(登录凭证)// localStorage.setItem("name", msg.value.username)// let info = {id: 1, name: msg.value.username, token: "ddsafhsjdfkj"}// store.doLogin(info)// // 3、跳转到首页// router.push({name: "mine"})
}</script><style scoped>
.box {width: 300px;margin: 100px auto;
}
</style>
4、现象:vue前端向后端API发送请求时有问题
Access to XMLHttpRequest at ‘http://127.0.0.1:8000/api/auth/’ from origin ‘http://localhost:5173’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
Access to XMLHttpRequest at ‘http://127.0.0.1:8000/api/auth/’ from origin ‘http://localhost:5173’ has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.
4.1 请求跨域问题
1、浏览器中有同源策略,当发送ajax请求:请求的地址与当前所在网址保持一致,如果不一致,浏览器就会阻止请求
2、为什么postman/requests不报错? 因为这俩软件没有同源策略的要求
3、在网站中用cdn地址? <script src='xxx'></script>
<img src='xxx'/>
无影响
4、项目开发时,会经常用到跨域
5、解决方式
- jsonp,发送ajax请求时,跨域会被浏览器阻止;所以不再使用ajax发送请求,而是构造script标签+src发送请求获取结果。
- cors:添加响应头,让浏览器别再限制
6、后端API如何实现CORS? 中间件
Access-Control-Allow-Origin:"*"
Access-Control-Allow-Headers: "*"
7、实现方式
utils/cors.py
from django.utils.deprecation import MiddlewareMixinclass CorsMiddleware(MiddlewareMixin):def process_response(self, request, response):response['Access-Control-Allow-Origin'] = "*"response['Access-Control-Allow-Headers'] = "*"return response
setting.py
MIDDLEWARE = [...'utils.cors.CorsMiddleware'
]
相关文章:

【VUE】案例:商场会员管理系统
编写vuedfr实现对会员进行基本增删改查 1. drf项目初始化 请求: POST http://127/0.0.0.1:8000/api/auth/ {"username":"cqn", "password":"123"}返回: {"username":"cqn", "token&q…...

IDEA 最新版创建 Sping Boot 项目没有 JDK8 选项的解决方案
问题 今天新建一个 Java 项目写 demo 时,发现 Idea 上只能勾选 Java 17、21、23 三个版本 解决方案 IDEA 页面创建 Spring 项目,其实是访问 spring initializr 去创建项目。我们可以通过阿里云国服去间接创建 Spring 项目。服务器 URL 地址替换为 ht…...

Unity Asset Store的默认下载位置及更改下载路径的方法
修改Unity Asset Store的默认下载路径 Unity Asset Store默认下载位置 Unity Asset Store里下载资源,默认是下载到C盘里的,如果你不想做C盘战士的话,记得将下载的资源转移到其他盘。 Unity商城默认下载路径是C:\用户\用户名(一般…...

ArcEngine实现要素坐标转换:平移、缩放、旋转(批量处理)
在二维坐标系统中,常见转换坐标:平移、缩放、旋转。在ArcGIS中可以通过工具实现移动 、旋转 和缩放,具体操作如下: (1)移动要素:可通过指针或指定值以交互方式操作所选要素。移动要素…...

Redis: 主从复制原理
主从复制原理剖析 1 )配置 通过下面的从节点的配置项可以开启主从之间的复制功能slaveof 192.16.10.101 6379这里的复制包含全量复制和增量复制 2 )主节点的主从配置信息解析 查看主从之间的信息,在主节点上 $ info replication 打印出来的…...
PostgreSQL 向量扩展插件pgvector安装和使用
文章目录 PostgreSQL 向量扩展插件pgvector安装和使用安装postgresqlpgvector下载和安装安装错误调试错误调试1尝试解决 AP1 :启动postgresql 错误调试2尝试解决 AP2 : 使用apt-get install postgresql-server 错误调试3尝试解决 AP3 :卸载apt-get 安装 …...
【论文阅读】基于真实数据感知的模型功能窃取攻击
摘要 目的 模型功能窃取攻击是人工智能安全领域的核心问题之一,目的是利用有限的与目标模型有关的信息训练出性能接近的克隆模型,从而实现模型的功能窃取。针对此类问题,一类经典的工作是基于生成模型的方法,这类方法利用生成器…...

线程池:线程池的实现 | 日志
🌈个人主页: 南桥几晴秋 🌈C专栏: 南桥谈C 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据…...
海信和TCL雷鸟智能电视的体验
买了型号为32E2F(9008)的海信智能的电视有一段时间了,要使用这个智能电视还真能考验你的智商。海信电视有很多优点,它的屏幕比较靓丽,色彩好看,遥控器不用对着屏幕就能操作。但也有不少缺点。 1. 海信智能电视会强迫自动更新操作…...

自动化学习3:日志记录及测试报告的生成--自动化框架搭建
一.日志记录 1.配置文件pytest.ini:将日志写入文件方便日后查询或查看执行信息。 需要将文件处理器(文件存放位置/时间/格式等等)添加到配置文件中的【日志记录器】 # pytest.ini [pytest] # ---------------日志文件,需要配合…...

【STM32单片机_(HAL库)】4-1【定时器TIM】定时器中断点灯实验
1.硬件 STM32单片机最小系统LED灯模块 2.软件 timer驱动文件添加定时器HAL驱动层文件添加GPIO常用函数定时器中断配置流程main.c程序 #include "sys.h" #include "delay.h" #include "led.h" #include "timer.h"int main(void) {H…...
Linux编译安装Mysql笔记
1.Mysql介绍 MySQL是一个广泛使用的开源关系型数据库管理系统(RDBMS),它基于SQL(Structured Query Language)进行操作。MySQL是由瑞典MySQL AB公司开发的,后来被Sun Microsystems收购,最终成为…...

在java后端发送HTTPClient请求
简介 HttpClient遵循http协议的客户端编程工具包支持最新的http协议 部分依赖自动传递依赖了HttpClient的jar包 明明项目中没有引入 HttpClient 的Maven坐标,但是却可以直接使用HttpClient原因是:阿里云的sdk依赖中传递依赖了HttpClient的jar包 发送get请…...

【STM32单片机_(HAL库)】4-3-2【定时器TIM】测量按键按下时间1——编程实现捕获功能
测量按键按下时长思路 测量按键按下时间实验目的 使用定时器 2 通道 2 来捕获按键 (按键接PA0)按下时间,并通过串口打印。 计一个数的时间:1us,PSC71,ARR65535 下降沿捕获、输入通道 2 映射在 TI2 上、不分…...
MySQL:2059 - Authentication plugin ‘caching_sha2_password‘ cannot be loaded
关于MySQL 客户端在尝试连接到 MySQL 服务器时报错:“2059 - Authentication plugin caching_sha2_password cannot be loaded”,具体是由于 MySQL 服务器默认使用的 caching_sha2_password 认证插件无法加载或不被当前客户端支持。 错误原因 MySQL 8.0…...

【JavaSE】反射、枚举、lambda表达式
目录 反射反射相关类获取类中属性相关方法常用获得类相关的方法示例常用获得类中属性相关的方法示例获得类中注解相关的方法 反射优缺点 枚举常用方法优缺点 枚举与反射lambda表达式语法函数式接口简化规则使用示例变量捕获集合中的应用优缺点 反射 Java的反射(refl…...
P3227 [HNOI2013] 切糕
题意: n ∗ m n*m n∗m的矩阵,每个点可以选择一个值 a i , j k a_{i,j}k ai,jk,然后你能获得 w ( i , j , k ) w(i,j,k) w(i,j,k)的得分,但是相邻两点之间的差值有限制,让你求最大得分。 考虑最小割。 每个点 ( i , j ) (i,j) (i,j)弄出一条长为 R…...

超分服务的分量保存
分量说明 分量的概念主要是对于显卡解码,编码和网络传输而言,显卡可以同时进行几个线程,多个显卡可以分布式计算,对分量进行AI识别,比如我们有cuda的显卡,cuda的核心量可以分给不同的分片视频,第…...

Windows11系统下SkyWalking环境搭建教程
目录 前言SkyWalking简介SkyWalking下载Agent监控实现启动配置SkyWalking启动Java应用程序启动Elasticsearch安装总结 前言 本文为博主在项目环境搭建时记录的SkyWalking安装流程,希望对大家能够有所帮助,不足之处欢迎批评指正🤝ᾑ…...
前端BOM常用操作
BOM操作常用命令详解及代码案例 BOM(Browser Object Model)是浏览器对象模型,是浏览器提供的JavaScript操作浏览器的API。BOM提供了与网页无关的浏览器的功能对象,虽然没有正式的标准,但现代浏览器已经几乎实现了Java…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
[特殊字符] 手撸 Redis 互斥锁那些坑
📖 手撸 Redis 互斥锁那些坑 最近搞业务遇到高并发下同一个 key 的互斥操作,想实现分布式环境下的互斥锁。于是私下顺手手撸了个基于 Redis 的简单互斥锁,也顺便跟 Redisson 的 RLock 机制对比了下,记录一波,别踩我踩过…...
stm32进入Infinite_Loop原因(因为有系统中断函数未自定义实现)
这是系统中断服务程序的默认处理汇编函数,如果我们没有定义实现某个中断函数,那么当stm32产生了该中断时,就会默认跑这里来了,所以我们打开了什么中断,一定要记得实现对应的系统中断函数,否则会进来一直循环…...
零基础在实践中学习网络安全-皮卡丘靶场(第十一期-目录遍历模块)
经过前面几期的内容我们学习了很多网络安全的知识,而这期内容就涉及到了前面的第六期-RCE模块,第七期-File inclusion模块,第八期-Unsafe Filedownload模块。 什么是"遍历"呢:对学过一些开发语言的朋友来说应该知道&…...

dvwa11——XSS(Reflected)
LOW 分析源码:无过滤 和上一关一样,这一关在输入框内输入,成功回显 <script>alert(relee);</script> MEDIUM 分析源码,是把<script>替换成了空格,但没有禁用大写 改大写即可,注意函数…...

【Elasticsearch基础】Elasticsearch批量操作(Bulk API)深度解析与实践指南
目录 1 Bulk API概述 1.1 什么是批量操作 1.2 Bulk API的优势 2 Bulk API的工作原理 2.1 请求处理流程 2.2 底层机制 3 Bulk API的使用方法 3.1 基本请求格式 3.2 操作类型示例 3.3 响应格式 4 Bulk API的最佳实践 4.1 批量大小优化 4.2 错误处理策略 4.3 性能调…...