【Python使用】嘿马云课堂web完整实战项目第4篇:封装异常处理,封装JSON返回值【附代码文档】

62 阅读1分钟

教程全知识点简介:数据模型 模板管理 模板管理业务流程 模板制作 GridFS研究 模板存储 静态化测试 页面预览 4 添加“页面预览”链接 页面发布 需求分析 技术方案 测试 课程管理 环境搭建 我的课程 数据字典 新增课程页面完善 新增课程服务端 课程信息修改 课程管理页面说明 服务端 前端 课程计划 页面原型 课程图片 上传图片开发 项目概述 项目背景 项目的功能构架 项目的技术架构 CMS 什么是CMS CMS需求分析与工程搭建 静态门户工程搭建 图片查询 前端开发 课程预览 课程预览技术方案 课程详情页面静态化 课程数据模型查询接口 课程信息模板设计 课程预览功能开发 CMS页面预览测试 CMS添加页面接口 课程发布 搜索服务 课程搜索需求分析 课程索引 准备课程索引信息 搭建ES环境 Logstash创建索引 搜索前端技术需求 了解SEO 服务端渲染和客户端渲染 Nuxt.js入门 创建Nuxt工程 页面布局 路由 搜索页面 分页查询 按分类搜索 集成测试 在线学习与媒资管理 在线学习需求分析 需求描述 视频点播解决方案 视频编码 生成m3u8/ts文件 播放器 后端工程搭建 导入CMS数据库 MongoEngine入门 在Django中使用MongoDB 定义文档 开发环境 上传文件 断点续传解决方案 文件分块与合并 前端页面 媒资服务端编写 媒体视频处理队列 媒体视频路由key 媒体处理交换机 加载可用的任务 保存视频信息 学习页面查询课程计划 Api接口 Logstash扫描课程计划媒资 搜索服务查询课程媒资接口 ESClient类 JWT 用户登录前端 用户注册后端 订单与选课 分布式事务 问题描述 CAP理论 解决方案 自动添加选课方案 增加数据 修改数据 删除数据 查询数据 Q对象 其他 查询集 QuerySet 页面管理后端开发 Celery Beat定时任务 订单服务定时发送消息 查询前N条任务 接口说明 接口开发规范 封装异常处理 封装JSON返回值 站点列表和模板列表接口 新增页面 页面查询接口定义 自定义条件查询 3 测试接口 页面详情 修改页面 删除页面 CMS前端工程创建 导入系统管理前端工程 单页面应用介绍 CMS前端页面查询开发 创建页面 Table组件测试 进入页面立即查询 前后端请求响应流程小结 新增页面前端开发 添加页面测试 页面处理流程 页面静态化及预览发布 页面静态化需求

👉👉👉   gitee.com/yinuo112/Ba…

封装异常处理

学习目标

  • 掌握统一异常处理封装的方法

1 接口异常返回

BookInfoViewSet视图集中模拟接口异常:

from rest_framework.exceptions import APIException


class BookInfoViewSet(ModelViewSet):
    ...
    def list(self, request, *args, **kwargs):
        raise APIException('请求出错!')
        return super().list(request, *args, **kwargs)

访问 http://localhost:8000/test/book/ 接口报错信息如下:

2 定义返回信息

我们将success、code、message封装到元组中,放到一个单独的文件中统一管理。

思考:有没有其他的数据结构来封装这些信息(namedtuple)?

新建common/response_code.py,添加我们系统用到的响应信息如下:

SUCCESS = (True, 10000, "操作成功!")
FAIL = (False, 11111, "操作失败!")
UNAUTHENTICATED = (False, 10001, "此操作需要登陆系统!")
UNAUTHORISE = (False, 10002, "权限不足,无权操作!")
INVALID_PARAM = (False, 10003, "非法参数!")
SERVER_ERROR = (False, 99999, "抱歉,系统繁忙,请稍后重试!")

UPLOAD_FILE_REGISTER_FAIL = (False, 22001, "上传文件在系统注册失败,请刷新页面重试!")
UPLOAD_FILE_REGISTER_EXIST = (False, 22002, "上传文件在系统已存在!")
CHUNK_FILE_EXIST_CHECK = (False, 22003, "分块文件在系统已存在!")
MERGE_FILE_FAIL = (False, 22004, "合并文件失败,文件在系统已存在!")
MERGE_FILE_CHECKFAIL = (False, 22005, "合并文件校验失败!")

AUTH_USERNAME_NONE = (False, 23001, "请输入账号!")
AUTH_PASSWORD_NONE = (False, 23002, "请输入密码!")
AUTH_VERIFYCODE_NONE = (False, 23003, "请输入!")
AUTH_ACCOUNT_NOTEXISTS = (False, 23004, "账号不存在!")
AUTH_CREDENTIAL_ERROR = (False, 23005, "账号或密码错误!")
AUTH_LOGIN_ERROR = (False, 23006, "登陆过程出现异常请尝试重新操作!")

CMS_ADDPAGE_EXISTSNAME = (False, 24001, "页面名称已存在!")
CMS_ADDPAGE_EXISTS = (False, 24002, "页面已存在!")
CMS_GENERATEHTML_DATAURLISNULL = (False, 24003, "从页面信息中找不到获取数据的url!")
CMS_GENERATEHTML_DATAISNULL = (False, 24004, "根据页面的数据url获取不到数据!")
CMS_GENERATEHTML_TEMPLATEISNULL = (False, 24005, "页面模板为空!")
CMS_GENERATEHTML_HTMLISNULL = (False, 24006, "生成的静态html为空!")
CMS_GENERATEHTML_SAVEHTMLERROR = (False, 24007, "保存静态html出错!")
CMS_PAGE_NOTEXISTS = (False, 24008, "页面不存在!")
CMS_COURSE_PERVIEWISNULL = (False, 24009, "预览页面为空!")

FS_UPLOADFILE_FILEISNULL = (False, 25001, "上传文件为空!")
FS_UPLOADFILE_BUSINESSISNULL = (False, 25002, "业务Id为空!")
FS_UPLOADFILE_SERVERFAIL = (False, 25003, "上传文件服务器失败!")
FS_DELETEFILE_NOTEXISTS = (False, 25004, "删除的文件不存在!")
FS_DELETEFILE_DBFAIL = (False, 25005, "删除文件信息失败!")
FS_DELETEFILE_SERVERFAIL = (False, 25006, "删除文件失败!")
FS_UPLOADFILE_METAERROR = (False, 25007, "上传文件的元信息请使用json格式!")
FS_UPLOADFILE_USERISNULL = (False, 25008, "上传文件用户为空!")

COURSE_NOTEXISTS = (False, 30001, "不存在")
COURSE_DENIED_DELETE = (False, 31001, "删除失败,只允许删除本机构的!")
COURSE_PUBLISH_PERVIEWISNULL = (False, 31002, "还没有进行预览!")
COURSE_PUBLISH_CDETAILERROR = (False, 31003, "创建详情页面出错!")
COURSE_PUBLISH_COURSEIDISNULL = (False, 31004, "Id为空!")
COURSE_PUBLISH_VIEWERROR = (False, 31005, "发布视图出错!")
COURSE_PUBLISH_CREATECOURSEPUB_ERROR = (False, 31006, "创建索引信息出错!"),
COURSE_TEACHPLAN_EXIST = (False, 31050, "已经绑定教学计划")
COURSE_TEACHPLAN_NOTEXISTS = (False, 31051, "计划不存在")
COURSE_MEDIS_URLISNULL = (False, 31101, "选择的媒资文件访问地址为空!")
COURSE_MEDIS_NAMEISNULL = (False, 31102, "选择的媒资文件名称为空!")
COURSE_MEDIA_TEACHPLAN_GRADEERROR = (False, 31104, "只允许选择第三级的计划关联视频!")
COURSE_PIC_NOTEXISTS = (False, 31201, "未找到图片!")
COURSE_PIC_UPLOAD_ERROR = (False, 31202, "图片上传失败!")

ORDER_ADD_ITEMISNULL = (False, 41001, "创建订单未选择!")
ORDER_ADD_ORDERNUMERROR = (False, 41002, "生成订单号错误!")
ORDER_ADD_GETCOURSEERROR = (False, 41003, "找不到信息!")
ORDER_FINISH_NOTFOUNDORDER = (False, 41004, "找不到订单信息!")
Pay_NOTFOUNDORDER = (False, 41010, "找不到要支付的订单!")
Pay_USERERROR = (False, 41011, "支付用户与订单用户不一致!")
Pay_NOTFOUNDPAY = (False, 41012, "支付记录不存在!")
COURSE_COMMENT_EXISTS = (False, 41031, "已评价!")

PortalView_ADDVIEWCOURSE_COURSEIDISNULL = (False, 42001, "id为空!")
PortalView_PUBLISH_PREVIEWCOURSE_ISNULL = (False, 42002, "预览视图为空!")
PortalView_PUBLISH_PREVIEWMEDIA_ISNULL = (False, 42003, "预览媒资视图为空!")

3 定制通用错误处理

要将对应的响应信息返回,我们采用定制exception_handler的方式

定义API异常类(common/exceptions.py)

from rest_framework.exceptions import APIException


class MyAPIException(APIException):
    """
    封装自己的异常处理类,用于返回标准异常信息
    """
    def __init__(self, detail=None, code=None):
        # 判断detail是否符合标准异常信息的格式
        if isinstance(detail, tuple) and len(detail) == 3:
            # 保存标准异常信息
            self._error_response = detail
        detail = self.default_detail
        if code is None:
            code = self.default_code
        super().__init__(detail=detail, code=code)

    # 封装方法获取异常代码信息
    def get_error_response(self):
        return self._error_response

定义异常处理函