【VUE】会员管理(增删改查)

embedded/2024/10/18 0:41:38/

前端

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: "home"}},{path: "home",name: "home",component: () => import('../views/HomeView.vue')},{path: "vip",name: "vip",component: () => import('../views/VipView.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

views/VipView.vue

<template><h1>会员管理</h1><button @click="doEdit">编辑</button><table border="1"><thead><tr><th>ID</th><th>姓名</th><th>级别</th><th>积分</th><th>操作</th></tr></thead><tbody><tr v-for="(item,idx) in dataList"><td>{{ item.id }}</td><td>{{ item.name }}</td><td>{{ item.level_text }}</td><td>{{ item.score }}</td><td><a>编辑</a>|<a>删除</a></td></tr></tbody></table><div v-show="dialog" class="mask"></div><div v-show="dialog" class="dialog"><input type="text"/><p><button>保存</button><button @click="dialog=false">取消</button></p></div>
</template><script setup>
import {ref} from "vue";const dataList = ref([{id: 1, name: "cc", age: 18, level_text: "SVIP", score: 1000}])
const dialog = ref(false)function doEdit() {dialog.value = true
}
</script><style scoped>
.mask {position: fixed;top: 0;bottom: 0;left: 0;right: 0;background-color: black;opacity: 0.8;z-index: 998;
}.dialog {position: fixed;top: 200px;right: 0;left: 0;width: 400px;height: 300px;background-color: white;margin: 0 auto;z-index: 9999;
}
</style>

后端

GET     http://127.0.0.1:8000/api/vip/          -> 会员列表
POST    http://127.0.0.1:8000/api/vip/          -> 新增会员(请求体中传入数据)
DELETE  http://127.0.0.1:8000/api/vip/会员ID/    -> 删除会员
PUT     http://127.0.0.1:8000/api/vip/会员ID/    -> 更新会员(请求体中传入数据)

urls.py

"""
from django.urls import path
from api.views import account
from api.views import vipurlpatterns = [path('api/auth/', account.AuthView.as_view()),path('api/vip/', vip.VipView.as_view()),path('api/vip/<int:vid>/', vip.VipDetailView.as_view()),
]

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)class Vip(models.Model):""" 会员管理 """name = models.CharField(verbose_name="用户名", max_length=32)level = models.IntegerField(verbose_name="级别", choices=[(1, "VIP"), (2, "SVIP"), (3, "SSVIP")])score = models.IntegerField(verbose_name="积分")

views/vip.py

from rest_framework.views import APIView
from api import models
from rest_framework import serializers
from rest_framework.response import Responseclass VipSerializers(serializers.ModelSerializer):level_text = serializers.CharField(source="get_level_display", read_only=True)class Meta:model = models.Vipfields = "__all__"class VipView(APIView):def get(self, request):# 会员列表queryset = models.Vip.objects.all().order_by("id")ser = VipSerializers(instance=queryset, many=True)return Response({"code": 0, "data": ser.data})def post(self, request):# 新增passclass VipDetailView(APIView):def delete(self, request, vid):# 删除passdef put(self, request, vid):# 修改pass

前端:VipView.vue

<template><h1>会员管理</h1><button @click="doEdit">编辑</button><table border="1"><thead><tr><th>ID</th><th>姓名</th><th>级别</th><th>积分</th><th>操作</th></tr></thead><tbody><tr v-for="(item,idx) in dataList"><td>{{ item.id }}</td><td>{{ item.name }}</td><td>{{ item.level_text }}</td><td>{{ item.score }}</td><td><a>编辑</a>|<a>删除</a></td></tr></tbody></table><div v-show="dialog" class="mask"></div><div v-show="dialog" class="dialog"><input type="text"/><p><button>保存</button><button @click="dialog=false">取消</button></p></div>
</template><script setup>
import {ref, onMounted} from "vue";
import _axios from "@/plugins/axios.js";const dataList = ref([{id: 1, name: "cc", age: 18, level_text: "SVIP", score: 1000}])
const dialog = ref(false)onMounted(function (){_axios.get("/api/vip/").then((res) => {console.log(res.data)dataList.value = res.data.data})
})
function doEdit() {dialog.value = true
}
</script><style scoped>
.mask {position: fixed;top: 0;bottom: 0;left: 0;right: 0;background-color: black;opacity: 0.8;z-index: 998;
}.dialog {position: fixed;top: 200px;right: 0;left: 0;width: 400px;height: 300px;background-color: white;margin: 0 auto;z-index: 9999;
}
</style>

删除

vip.py

from rest_framework.views import APIView
from api import models
from rest_framework import serializers
from rest_framework.response import Responseclass VipSerializers(serializers.ModelSerializer):level_text = serializers.CharField(source="get_level_display", read_only=True)class Meta:model = models.Vipfields = "__all__"class VipView(APIView):def get(self, request):# 会员列表queryset = models.Vip.objects.all().order_by("id")ser = VipSerializers(instance=queryset, many=True)return Response({"code": 0, "data": ser.data})def post(self, request):# 新增passclass VipDetailView(APIView):def delete(self, request, vid):# 删除models.Vip.objects.filter(id=vid).delete()return Response({"code": 0})def put(self, request, vid):# 修改pass

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'] = "*"response['Access-Control-Allow-Methods'] = "*"return response

前端
VipView.vue

<template><h1>会员管理</h1><button @click="doEdit">新增</button><table border="1"><thead><tr><th>ID</th><th>姓名</th><th>级别</th><th>积分</th><th>操作</th></tr></thead><tbody><tr v-for="(item,idx) in dataList"><td>{{ item.id }}</td><td>{{ item.name }}</td><td>{{ item.level_text }}</td><td>{{ item.score }}</td><td><a>编辑</a>|<button @click="doDelete(item.id, idx)">删除</button></td></tr></tbody></table><div v-show="dialog" class="mask"></div><div v-show="dialog" class="dialog"><input type="text"/><p><button>保存</button><button @click="dialog=false">取消</button></p></div>
</template><script setup>
import {ref, onMounted} from "vue";
import _axios from "@/plugins/axios.js";const dataList = ref([{id: 1, name: "cc", age: 18, level_text: "SVIP", score: 1000}])
const dialog = ref(false)onMounted(function () {_axios.get("/api/vip/").then((res) => {console.log(res.data)dataList.value = res.data.data})
})function doEdit() {dialog.value = true
}function doDelete(vid, idx) {_axios.delete(`/api/vip/${vid}/`).then((res) => {// console.log(res.data)if (res.data.code === 0) {dataList.value.splice(idx, 1)}})
}
</script><style scoped>
.mask {position: fixed;top: 0;bottom: 0;left: 0;right: 0;background-color: black;opacity: 0.8;z-index: 998;
}.dialog {position: fixed;top: 200px;right: 0;left: 0;width: 400px;height: 300px;background-color: white;margin: 0 auto;z-index: 9999;
}
</style>

增加

后端:vip.py

from rest_framework.views import APIView
from api import models
from rest_framework import serializers
from rest_framework.response import Responseclass VipSerializers(serializers.ModelSerializer):level_text = serializers.CharField(source="get_level_display", read_only=True)class Meta:model = models.Vipfields = "__all__"class VipView(APIView):def get(self, request):# 会员列表queryset = models.Vip.objects.all().order_by("id")ser = VipSerializers(instance=queryset, many=True)return Response({"code": 0, "data": ser.data})def post(self, request):""" 新增 """# 1.获取数据 request.data# 2.校验数据ser = VipSerializers(data=request.data)if not ser.is_valid():return Response({"code": 1000, "msg": "校验失败", "detail": ser.errors})# 3.保存ser.save()# 4.返回return Response({"code": 0, "data": ser.data})class VipDetailView(APIView):def delete(self, request, vid):# 删除models.Vip.objects.filter(id=vid).delete()return Response({"code": 0})def put(self, request, vid):# 修改pass

前端:VipView.vue

<template><h1>会员管理</h1><button @click="doEdit">新增</button><table border="1"><thead><tr><th>ID</th><th>姓名</th><th>级别</th><th>积分</th><th>操作</th></tr></thead><tbody><tr v-for="(item,idx) in dataList"><td>{{ item.id }}</td><td>{{ item.name }}</td><td>{{ item.level_text }}</td><td>{{ item.score }}</td><td><a>编辑</a>|<button @click="doDelete(item.id, idx)">删除</button></td></tr></tbody></table><div v-show="dialog" class="mask"></div><div v-show="dialog" class="dialog"><p><input type="text" placeholder="姓名" v-model="form.name"></p><p><select v-model="form.level"><option v-for="item in levelList" :value="item.id">{{ item.text }}</option></select></p><p><input type="text" placeholder="积分" v-model="form.score"></p><p><button @click="doSave">提交</button><button @click="dialog=false">取消</button></p></div>
</template><script setup>
import {ref, onMounted} from "vue";
import _axios from "@/plugins/axios.js";const dataList = ref([{id: 1, name: "cc", age: 18, level_text: "SVIP", score: 1000}])
const dialog = ref(false)
const levelList = ref([{id: 1, "text": "普通会员"},{id: 2, "text": "超级会员"},{id: 3, "text": "超超级会员"},
])
const form = ref({name: "",level: 1,score: 100
})onMounted(function () {_axios.get("/api/vip/").then((res) => {console.log(res.data)dataList.value = res.data.data})
})function doEdit() {dialog.value = true
}function doSave() {_axios.post("/api/vip/", form.value).then((res) => {console.log(res.data)if (res.data.code === 0) {dataList.value.push(res.data.data)// dataList.value.unshift(res.data.data)   // 往最前面添加dialog.value = falseform.value = {name: "",level: 1,score: 100}}})
}function doDelete(vid, idx) {_axios.delete(`/api/vip/${vid}/`).then((res) => {// console.log(res.data)if (res.data.code === 0) {dataList.value.splice(idx, 1)}})
}
</script><style scoped>
.mask {position: fixed;top: 0;bottom: 0;left: 0;right: 0;background-color: black;opacity: 0.8;z-index: 998;
}.dialog {position: fixed;top: 200px;right: 0;left: 0;width: 400px;height: 300px;background-color: white;margin: 0 auto;z-index: 9999;
}
</style>

编辑

前端:VipView.vue

<template><h1>会员管理</h1><button @click="doAdd">新增</button><table border="1"><thead><tr><th>ID</th><th>姓名</th><th>级别</th><th>积分</th><th>操作</th></tr></thead><tbody><tr v-for="(item,idx) in dataList"><td>{{ item.id }}</td><td>{{ item.name }}</td><td>{{ item.level_text }}</td><td>{{ item.score }}</td><td><button @click="doEdit(item.id, idx)">编辑</button>|<button @click="doDelete(item.id, idx)">删除</button></td></tr></tbody></table><div v-show="dialog" class="mask"></div><div v-show="dialog" class="dialog"><p><input type="text" placeholder="姓名" v-model="form.name"></p><p><select v-model="form.level"><option v-for="item in levelList" :value="item.id">{{ item.text }}</option></select></p><p><input type="text" placeholder="积分" v-model="form.score"></p><p><button @click="doSave">提交</button><button @click="dialog=false; editId=-1; editIdx=-1">取消</button></p></div>
</template><script setup>
import {ref, onMounted} from "vue";
import _axios from "@/plugins/axios.js";// const dataList = ref([{id: 1, name: "cc", age: 18, level_text: "SVIP", score: 1000}])
const dataList = ref([{}])
const dialog = ref(false)
const levelList = ref([{id: 1, "text": "普通会员"},{id: 2, "text": "超级会员"},{id: 3, "text": "超超级会员"},
])
const form = ref({name: "",level: 1,score: 100
})
const editId = ref(-1)
const editIdx = ref(-1)onMounted(function () {_axios.get("/api/vip/").then((res) => {console.log(res.data)dataList.value = res.data.data})
})function doAdd() {dialog.value = true
}function doSave() {if (editId.value === -1){// 新增_axios.post("/api/vip/", form.value).then((res) => {console.log(res.data)if (res.data.code === 0) {dataList.value.push(res.data.data)// dataList.value.unshift(res.data.data)   // 往最前面添加dialog.value = falseform.value = {name: "",level: 1,score: 100}}})} else {// 更新_axios.put(`/api/vip/${editId.value}/`, form.value).then((res) => {if (res.data.code === 0) {dataList.value[editIdx.value] = res.data.datadialog.value = falseform.value = {name: "",level: 1,score: 100}editId.value = -1editIdx.value = -1}})}}function doEdit(vid, idx) {// 显示编辑的值let editDict = dataList.value[idx]form.value = {name: editDict.name,level: editDict.level,score: editDict.score}// 当前编辑行的ideditId.value = videditIdx.value = idxdialog.value = true
}function doDelete(vid, idx) {_axios.delete(`/api/vip/${vid}/`).then((res) => {// console.log(res.data)if (res.data.code === 0) {dataList.value.splice(idx, 1)}})
}
</script><style scoped>
.mask {position: fixed;top: 0;bottom: 0;left: 0;right: 0;background-color: black;opacity: 0.8;z-index: 998;
}.dialog {position: fixed;top: 200px;right: 0;left: 0;width: 400px;height: 300px;background-color: white;margin: 0 auto;z-index: 9999;
}
</style>

后端:vip.py

from rest_framework.views import APIView
from api import models
from rest_framework import serializers
from rest_framework.response import Responseclass VipSerializers(serializers.ModelSerializer):level_text = serializers.CharField(source="get_level_display", read_only=True)class Meta:model = models.Vipfields = "__all__"class VipView(APIView):def get(self, request):# 会员列表queryset = models.Vip.objects.all().order_by("id")ser = VipSerializers(instance=queryset, many=True)return Response({"code": 0, "data": ser.data})def post(self, request):""" 新增 """# 1.获取数据 request.data# 2.校验数据ser = VipSerializers(data=request.data)if not ser.is_valid():return Response({"code": 1000, "msg": "校验失败", "detail": ser.errors})# 3.保存ser.save()# 4.返回return Response({"code": 0, "data": ser.data})class VipDetailView(APIView):def delete(self, request, vid):# 删除models.Vip.objects.filter(id=vid).delete()return Response({"code": 0})def put(self, request, vid):""" 修改 """# 1.获取数据 request.datainstance = models.Vip.objects.filter(id=vid).first()# 2.校验数据ser = VipSerializers(data=request.data, instance=instance)if not ser.is_valid():return Response({"code": 1000, "msg": "校验失败", "detail": ser.errors})# 3.保存ser.save()# 4.返回return Response({"code": 0, "data": ser.data})

后端:

  • 成功后统一化返回值,统一异常处理,ModelViewSet(忽略分页)
  • 添加认证,认证成功后才可以访问接口

http://www.ppmy.cn/embedded/126982.html

相关文章

软件测试学习笔记丨tcpdump 与 wireshark

本文转自测试人社区&#xff0c;原文链接&#xff1a;https://ceshiren.com/t/topic/32333 一、抓包分析TCP协议 1.1 简介 TCP协议是在传输层中&#xff0c;一种面向连接的、可靠的、基于字节流的传输层通信协议。 1.2 环境准备 对接口测试工具进行分类&#xff1a; 网络嗅…

华为公有云实战

1.申请一台ECS云主机&#xff0c;并且可以提供web服务 1.1访问云主机-华为特有技术novnc&#xff0c;KVM中提到vnc技术&#xff0c;novnc是不用安装vnc客户端用浏览器html语言实现。 1.2cloudshell 1.3小工具 ssh 弹性ip 1.4.安装httpd服务 建立索引文件 浏览器上输入弹性ip可…

Spark第一天

MapReduce过程复习 Spark由五部分组成 RDD五大特征 1、 Spark -- 代替MapReduce <<<<< scala是单机的&#xff0c;spark是分布式的。>>>>> 开源的分布式计算引擎 可以快速做计算 -- 因为可以利用内存来做一些计算 (1) 分为5个库(模块) : 1、…

数据结构之旅(顺序表)

前言: Hello,各位小伙伴们我们在过去的60天里学完了C语言基本语法,由于小编在准备数学竞赛,最近没有给大家更新,并且没有及时回复大家的私信,小编在这里和大家说一声对不起!,小编这几天会及时给大家更新初阶数据结构的内容,然后我们来学习今天的内容吧! 一. 顺序表的概念和结…

UE5+ChatGPT实现3D AI虚拟人综合实战

第11章 综合实战&#xff1a;UE5ChatGPT实现3D AI虚拟人 通过结合Unreal Engine 5&#xff08;UE5&#xff09;的强大渲染能力和ChatGPT的自然语言处理能力&#xff0c;我们可以实现一个高度交互性的AI虚拟人。本文将详细介绍如何在UE5中安装必要的插件&#xff0c;配置OpenAI…

Fiddler配合wireshark解密ssl

环境&#xff1a; win11&#xff08;wireshark&#xff09;--虚拟机win7&#xff08;Fiddler&#xff09;---虚拟机win7&#xff08;HTTPS站点&#xff09; 软件安装问题&#xff1a; 需要.net环境&#xff0c;NDP461-KB3102436-x86-x64-AllOS-ENU.exe。 安装fiddler后安装下…

自动驾驶 车道检测实用算法

自动驾驶 | 车道检测实用算法 车道识别是自动驾驶领域的一个重要问题&#xff0c;今天介绍一个利用摄像头图像进行车道识别的实用算法。该算法利用了OpenCV库和Udacity自动驾驶汽车数据库的相关内容。 该算法包含以下步骤&#xff1a; 摄像头校准&#xff0c;以移除镜头畸变&…

SldWorks问题 2. 矩阵相关接口使用上的失误

问题 在计算三维点在图纸&#xff08;DrawingDoc&#xff09;中的位置时&#xff0c;就是算不对&#xff0c;明明就4、5行代码&#xff0c;怎么看都是很“哇塞”的&#xff0c;毫无问题的。 但结果就是不对。 那就调试一下吧&#xff0c;调试后发现生成的矩阵很不对劲&#…