【VUE+DRF】案例升级

1、功能完善(简易版)

1.1 后端API校验

基于drf的认证组件实现只有登录之后才能查看

utils/auth.py

from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import APIException, AuthenticationFailed
from rest_framework import status
from api import modelsclass MineAuthenticationFailed(APIException):status_code = status.HTTP_200_OKclass MineAuthentcation(BaseAuthentication):def authenticate(self, request):token = request.query_params.get("token")if not token:raise MineAuthenticationFailed("token不存在")user_object = models.UserInfo.objects.filter(token=token).first()if not user_object:raise MineAuthenticationFailed("认证失败")return user_object, token

settings.py


REST_FRAMEWORK = {"DEFAULT_AUTHENTICATION_CLASSES": ["utils.auth.MineAuthentcation"],
}

account.py

class AuthView(MineApiView):authentication_classes = []

1.2 前端校验

axios.js

const _axios = axios.create(config)
const info = userInfoStore()_axios.interceptors.request.use(function (config) {// console.log("请求拦截器:", config)// 1. 去pinia中读取当前用户token// 2. 发送请求时携带tokenif (info.userToken) {if (config.params) {config.params["token"] = info.userToken} else {config.params = {"token": info.userToken}}}return config
})
_axios.interceptors.response.use(function (response) {console.log("响应拦截器:", response)// 认证失败if (response.data.code === "1000") {router.replace({name: "login"})}return response
}, function (error) {console.log("拦截器异常", error)if (error.response.data.code === "1000") {router.replace({name: "login"})}return Promise.reject(error)
})export default _axios

LoginView.vue

const doLogin = function () {// 1、获取数据console.log(msg.value)// 2、发送网络请求_axios.post("/api/auth/", msg.value).then((res) => {console.log(res.data)if (res.data.code === 0){store.doLogin(res.data.data)router.push({name: "home"})} else {error.value = res.data.msgsetTimeout(function (){error.value=""}, 5000)}})
}

2、后端API升级

2.1 正常请求返回

utils/views.py

class BaseAPIView:def finalize_response(self, request, response, *args, **kwargs):response = super().finalize_response(request, response, *args, **kwargs)# 1. 非正常if response.exception:return response# 2. 正常response.data = {"code": 0, "data": response.data}return response

vip.py

from rest_framework.views import APIView
from api import models
from rest_framework import serializers
from rest_framework.response import Response
from rest_framework.exceptions import ValidationError
from utils.exc_views import ExtraExceptions
from utils.views import BaseAPIViewclass VipSerializers(serializers.ModelSerializer):level_text = serializers.CharField(source="get_level_display", read_only=True)class Meta:model = models.Vipfields = "__all__"class VipView(BaseAPIView, APIView):def get(self, request):# 会员列表queryset = models.Vip.objects.all().order_by("id")ser = VipSerializers(instance=queryset, many=True)return Response(ser.data)def post(self, request):""" 新增 """# 1.获取数据 request.data# 2.校验数据ser = VipSerializers(data=request.data)print(request.data)exist = models.Vip.objects.filter(name=request.data["name"]).exists()if exist:raise ValidationError({"msg": "会员已存在"})if not ser.is_valid():raise ValidationError({"msg": "校验失败", "detail": ser.errors})# 3.保存ser.save()# 4.返回return Response(ser.data)class VipDetailView(BaseAPIView, APIView):def delete(self, request, vid):# 删除  ?返回已删除的数据models.Vip.objects.filter(id=vid).delete()return Response({"msg": "删除成功"})def put(self, request, vid):""" 修改 """# 1.获取数据 request.datainstance = models.Vip.objects.filter(id=vid).first()""" BUG:id不存在时,会进行新增操作 """if not instance:raise ExtraExceptions("id不存在,无法更新")# 2.校验数据ser = VipSerializers(data=request.data, instance=instance)if not ser.is_valid():raise ValidationError({"msg": "校验失败", "detail": ser.errors})# 3.保存ser.save()# 4.返回return Response({"data": ser.data})

2.2 异常请求返回

utils/views.py

class ExtraExceptions(APIException):passdef exception_handler(exc, context):if isinstance(exc, Http404):exc.ret_code = 1001exc = exceptions.NotFound(*exc.args)elif isinstance(exc, PermissionDenied):exc.ret_code = 1002exc = exceptions.PermissionDenied(*exc.args)elif isinstance(exc, (AuthenticationFailed, NotAuthenticated)):exc.ret_code = 1003elif isinstance(exc, Throttled):exc.ret_code = 1004if isinstance(exc, exceptions.APIException):headers = {}if getattr(exc, 'auth_header', None):headers['WWW-Authenticate'] = exc.auth_headerif getattr(exc, 'wait', None):headers['Retry-After'] = '%d' % exc.waitexc_code = getattr(exc, "ret_code", None) or -1data = {"code": exc_code, "detail": exc.detail}set_rollback()return Response(data, status=exc.status_code, headers=headers)data = {"code": -1, "detail": str(exc)}return Response(data, status=500)

vip.py

from api import models
from rest_framework.views import APIView
from rest_framework import serializers
from rest_framework.response import Response
from rest_framework.exceptions import ValidationError
from utils.views import BaseAPIView, ExtraExceptionsclass VipSerializers(serializers.ModelSerializer):level_text = serializers.CharField(source="get_level_display", read_only=True)class Meta:model = models.Vipfields = "__all__"class VipView(BaseAPIView, APIView):def get(self, request):# 会员列表queryset = models.Vip.objects.all().order_by("id")ser = VipSerializers(instance=queryset, many=True)return Response(ser.data)def post(self, request):""" 新增 """# 1.获取数据 request.data# 2.校验数据ser = VipSerializers(data=request.data)print(request.data)exist = models.Vip.objects.filter(name=request.data["name"]).exists()if exist:raise ValidationError({"msg": "会员已存在"})if not ser.is_valid():raise ValidationError({"msg": "校验失败", "detail": ser.errors})# 3.保存ser.save()# 4.返回return Response(ser.data)class VipDetailView(BaseAPIView, APIView):def delete(self, request, vid):# 1.获取数据 request.datainstance = models.Vip.objects.filter(id=vid).first()if not instance:raise ExtraExceptions("id不存在,无法删除")# 删除  ?返回已删除的数据models.Vip.objects.filter(id=vid).delete()return Response({"msg": "删除成功"})def put(self, request, vid):""" 修改 """# 1.获取数据 request.datainstance = models.Vip.objects.filter(id=vid).first()""" BUG:id不存在时,会进行新增操作 """if not instance:raise ExtraExceptions("id不存在,无法更新")# 2.校验数据ser = VipSerializers(data=request.data, instance=instance)if not ser.is_valid():raise ValidationError({"msg": "校验失败", "detail": ser.errors})# 3.保存ser.save()# 4.返回return Response(ser.data)

account.py

import uuid
from rest_framework import serializers
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.exceptions import AuthenticationFailed
from api import models
from utils.views import BaseAPIViewclass AuthSerializer(serializers.Serializer):username = serializers.CharField(required=True)password = serializers.CharField(required=True)class AuthView(BaseAPIView, APIView):authentication_classes = []def post(self, request):# 1. 获取用户提交数据 request.data = {"username": "xxx", "password": "...}# 2. 表单校验ser = AuthSerializer(data=request.data)# if not ser.is_valid():#     raise ValidationError({"msg": "校验失败", "detail": ser.errors})ser.is_valid(raise_exception=True)# 3. 数据库校验user_object = models.UserInfo.objects.filter(**ser.data).first()if not user_object:raise AuthenticationFailed("用户名或密码错误")token = uuid.uuid4()user_object.token = tokenuser_object.save()# 4. 数据返回return Response({"id": user_object.id, "name": user_object.username, "token": user_object.token})

2.3 业务功能开发(路由+视图+序列化器)

urls.py

from django.urls import path
from api.views import account
from api.views import vip, vip2
from rest_framework import routersrouter = routers.SimpleRouter()
router.register(r"api/vip2", vip2.VipView)urlpatterns = [path('api/auth/', account.AuthView.as_view()),path('api/vip/', vip.VipView.as_view()),path('api/vip/<int:vid>/', vip.VipDetailView.as_view()),
]
urlpatterns += router.urls

utils/pagination.py

from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Responseclass MinePageNumberPagination(PageNumberPagination):def get_paginated_response(self, data):return Response({'totalCount': self.page.paginator.count,'perpageCount': self.page_size,'results': data,})

settings.py


REST_FRAMEWORK = {"EXCEPTION_HANDLER": "utils.views.exception_handler","DEFAULT_AUTHENTICATION_CLASSES": ["utils.auth.MineAuthentcation"],"DEFAULT_PAGINATION_CLASS": "utils.pagination.MinePageNumberPagination","PAGE_SIZE": 5,
}

vip2.py

from rest_framework.viewsets import ModelViewSet
from api import models
from rest_framework import serializers
from utils.views import BaseAPIViewclass VipSerializers(serializers.ModelSerializer):level_text = serializers.CharField(source="get_level_display", read_only=True)class Meta:model = models.Vipfields = "__all__"class VipView(BaseAPIView, ModelViewSet):serializer_class = VipSerializersqueryset = models.Vip.objects.all().order_by("id")

3、前端页面升级

3.1 Flex布局

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/59471.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

背靠背MOS管-锂电池充放电控制详解

目录&#xff1a; 1、概述 2、外接适配器 3、使用锂电池 4、电池检测回路 1、概述 本锂电池充放电控制电路采用 TP4055 作为电池 BAT 的充电控制&#xff0c;如下图1.1绿色框所示。 TP4055 引脚功能描述&#xff1a; 1CHRG开漏输出的充电状态指示引脚&#xff0c;需要上…

嵌入式软件八股文

1.指针的大小是固定的&#xff0c;和指针的类型没有关系 只与编译器有关&#xff0c;32位系统指针大小为8个字节&#xff0c;x64一般为64位系统&#xff0c;指针大小一般为4个字节。 2.sizeof()和strlen() sizeof()计算所占内存的大小,可以计算int float大小 strlen()计算的…

美畅物联丨物联网通信新纪元:Cat.1与5G RedCap的差异化应用

​ 在物联网&#xff08;IoT&#xff09;迅猛发展的时代&#xff0c;通信标准对物联网设备的连接性、性能和适用性有着极为关键的作用。小编在《美畅物联丨Cat.1与NB-IoT&#xff1a;物联网设备的通信标准对比》中提到Cat.1与NB-IoT的对比区别&#xff0c;后来就有小伙伴问&…

单表查询题库

1. 查看course表结构的SQL命令是什么&#xff1f; A. SELECT * FROM exam.course; B. \d exam.course; C. \d exam.course; D. DESCRIBE exam.course; 答案&#xff1a;C 2. 使用哪个SQL命令可以查看exam.course表中的所有数据&#xff1f; A. SELECT * FROM e…

vue用jenkins 打包项目项目关闭eslint检查

问题描述&#xff1a;创建vue脚手架项目后&#xff0c;使用jenkins 打包项目&#xff0c;出现如下图所示错误&#xff0c;显示错误来源于eslint检测。 解决方法&#xff1a;在根目录下找到vue.config.js文件&#xff0c;添加lintOnSave: false以关闭eslint检测&#xff0c;项目…

序列中删除指定数字【四种解法】

文章目录 解法1&#xff1a;另辟空间法解法2&#xff1a;覆盖法解法3&#xff1a;覆盖法&#xff08;进阶版&#xff09;解法4&#xff1a;异或取巧法 题目&#xff1a;有一个整数序列&#xff08;可能存在重复的整数&#xff09;&#xff0c;编写程序删除序列中指定的某一个整…

【p2p、分布式,区块链笔记 Torrent】WebTorrent的add和seed函数

在【p2p、分布式&#xff0c;区块链笔记 Torrent】WebTorrent的上传和下载界面的示例中&#xff0c;主要通过WebTorrent类的add和seed函数实现相关功能。这两个函数都返回一个Torrent类对象的实例。 seed函数 import createTorrent, { parseInput } from create-torrent // &…

【07】Maven项目多环境打包配置

&#xff08;1&#xff09;Web项目使用Maven进行多模块划分开发之后&#xff0c;面临一个问题&#xff0c;即如何加载不同环境的配置文件打包发布到不同的环境中&#xff1f; &#xff08;2&#xff09;不同的环境有开发环境、测试环境、线上生产环境等。 &#xff08;3&#x…

机器学习—前向传播的一般实现

可以写一个函数来实现一个密集的层&#xff0c;那是神经网络的单层&#xff0c;所以定义稠密函数&#xff0c;它将上一层的激活作为输入以及给定层神经元的参数w和b。看下边图片所展示的例子&#xff0c;把所有这些权重向量堆叠成一个矩阵&#xff0c;wnp.array([[1,-3,5][2,4,…

濮良贵《机械设计》第十版课后习题答案全解PDF电子版

《机械设计》(第十版)是“十二五”普通高等教育本科国家级规划教材&#xff0c; 是在《机械设计》(第九版)的基础上修订而成的。本次修订主要做了以下几项工作&#xff1a; 1. 内容的适当更新——自本书第九版出版以来&#xff0c; 机械工程及相关领域的新理论、新技术和新标准…

1分钟解决Excel打开CSV文件出现乱码问题

一、编码问题 1、不同编码格式 CSV 文件有多种编码格式&#xff0c;如 UTF - 8、UTF - 16、ANSI 等。如果 CSV 文件是 UTF - 8 编码&#xff0c;而 Excel 默认使用的是 ANSI 编码打开&#xff0c;就可能出现乱码。例如&#xff0c;许多从网络应用程序或非 Windows 系统生成的 …

曹操出行借助 ApsaraMQ for Kafka Serverless 提升效率,成本节省超 20%

本文整理于 2024 年云栖大会主题演讲《云消息队列 ApsaraMQ Serverless 演进》&#xff0c;杭州优行科技有限公司消息中间件负责人王智洋分享 ApsaraMQ for Kafka Serverless 助力曹操出行实现成本优化和效率提升的实践经验。 曹操出行&#xff1a;科技驱动共享出行未来 曹操…

解析 MySQL 数据库容量统计、存储限制与优化技巧

管理 MySQL 数据库时&#xff0c;了解数据库中的数据量和存储占用情况是非常重要的&#xff0c;尤其是在面对大规模数据时。无论是为了优化数据库性能&#xff0c;还是为了进行容量规划&#xff0c;准确地统计数据库的容量可以帮助我们做出更好的决策。mysql的客户端工具是Navi…

【研究生必备】如何利用AI论文生成器免费提升效率?

在研究生阶段&#xff0c;写论文往往是学业中最具挑战性的部分之一。 面对繁重的文献阅读、复杂的分析和紧迫的时间限制&#xff0c;很多同学都感到压力倍增。不过&#xff0c;随着科技的发展&#xff0c;AI论文生成器的出现为我们提供了一种全新的解决方案。今天&#xff0c;…

Android无限层扩展多级recyclerview列表+实时搜索弹窗

业务逻辑&#xff1a; 点击选择&#xff0c;弹出弹窗&#xff0c;列表数据由后台提供&#xff0c;不限层级&#xff0c;可叠加无限层子级&#xff1b; 点击item展开收起&#xff0c;点击尾部icon单选选中&#xff0c;点击[确定]为最终选中&#xff0c;收起弹窗&#xff1b; 搜索…

位运算的使用与计算机组成的底层计算(java版)

目录 1. 求int类型数字的二进制2. 特殊值展示3. 心得 1. 求int类型数字的二进制 我们可以用位运算的与和左移去求 public class Lesson01 {public static void print(int num){for(int i 31; i >0; i--){System.out.print((num & (1 << i)) 0 ? "0&quo…

写作 | 人工智能在师生教学场景中的应用前景

正文 本文讨论人工智能在师生教学场景中的应用前景。在开展论述前&#xff0c;首先需要明确一些概念。 第一&#xff0c;什么是人工智能&#xff1f;人工智能&#xff08;Artificial Intelligence&#xff09;&#xff0c; 字面意义&#xff0c;即人工制作的智慧能力。这种智慧…

Java线程6种生命周期及转换

多线程技术是我们后端工程师在面试的时候必问的一个知识点&#xff0c;今天就来盘点一下多线程的相关知识&#xff0c; 先来说下进程&#xff0c;线程及线程的生命周期&#xff1a; 进程&#xff1a;进程就是正在进行中的程序&#xff0c;是没有生命的实体&#xff0c;只有在运…

美格智能5G车规级通信模组: 5G+C-V2X连接汽车通信未来十年

自2019年5G牌照发放开始&#xff0c;经过五年发展&#xff0c;我国5G在基础设施建设、用户规模、创新应用等方面均取得了显著成绩&#xff0c;5G网络建设也即将从基础的大范围覆盖向各产业融合的全场景应用转变。工业和信息化部数据显示&#xff0c;5G行业应用已融入76个国民经…

GooglePlay: 应用和游戏的内容分级

对于后台私信的开发者们,希望能够携带详细过审记录和拒审邮件一同发来,方便我们尽快解决问题 应用与游戏 为您的应用或游戏选择类别和标签选择要添加的标签选择类别并添加标签类别示例与应用、游戏以及两者中所投放广告的内容分级相关的要求应用如何获得内容分级内容分级的用…