持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情
大家好~我是小方,欢迎大家关注笋货测试笔记体完记得俾个like呀
接上篇
上篇我们编写了第一个接口--注册接口,但是代码还有很多可以优化的地方,今天我们来一个个优化~
工具类补充
- 自定义异常类
- 上篇我们讲到抛异常时,没有处理,后端服务直接报500了,这次我们要加上通用捕获异常类
app/utils新建exception_utils.py写一个通用捕获异常类
from fastapi import HTTPException
from typing import Any
# 通用异常类
class NormalException(HTTPException):
def __init__(self, detail: Any = None) -> None:
super().__init__(status_code=200, detail=detail)
app/routers/user/user.py引入该异常类,完整代码如下
from fastapi import APIRouter
from app.routers.user.user_schema import RegisterUserBody
from app.curd.user.UserDao import UserDao
from app.utils.exception_utils import NormalException
router = APIRouter()
@router.post('/register', name='用户注册', description='用户注册')
def register(data: RegisterUserBody):
try:
UserDao.register_user(**data.dict())
return dict(code=200, msg='注册成功')
except Exception as e:
raise NormalException(str(e))
- 日志装饰器
- 编写UserDao时,需要手动try...except...,比较繁琐,这里的话,加个装饰器就好了,给方法戴顶帽子
# 捕获异常装饰器
def record_log(func):
functools.wraps(func)
def wrapper(*args, **kwargs):
cls = args[0]
try:
return func(*args, **kwargs)
except Exception as e:
# 获取函数名成
func_name = func.__name__
import traceback
err = traceback.format_exc()
# 日志输出详细报错信息
cls.log.error(f"{func_name}失败: {err}")
raise Exception(str(e))
return wrapper
改造一下UserDao.py
优化返参
本来这一块我打算用回原来的返参方法,直接传入msg,code,data实现返参格式的统一,但是后来看了一下官网的推荐写法,官网推荐维护成一个模型(使用response_model)那就在这里试试用新方法吧~
新建
app/models/base.py文件,里面维护返参模型
app/routers/user/user.py引入该返参模型
先来测试一下,测试成功~
schema代码优化
user表的密码明文存储,不太友好,其实这个可以在定义模型的时候,给密码字段加个加密方法即可
app/routers/user/user_schema.py加入这个方法,为了更加安全,这里我还设置了一个盐值
config.py记得加上KEY
对了,这里的
check_field考虑到后续用得比较多,这里将其抽成一个公共方法,直接将它cv到app/models/base.py
对了,email字段不再是str类型了,是EmailStr类型!!!这里记得安装
email-validator
app/routers/user/user_schema.py完整代码如下:
from pydantic import BaseModel, validator, Field, EmailStr
from config import Config
import hashlib
from app.models.base import ToolsSchemas
class RegisterUserBody(BaseModel):
username: str = Field(..., title="用户名", description="必传")
password: str = Field(..., title="密码", description="必传")
name: str = Field(..., title="姓名", description="必传")
email: EmailStr = Field(..., title="邮箱号", description="必传")
@validator('username', 'password', 'name', 'email')
def check_field(cls, v):
return ToolsSchemas.not_empty(v)
@validator('password')
def md5_paw(cls, value):
m = hashlib.md5()
m.update(f"{value}key={Config.KEY}".encode("utf-8"))
return m.hexdigest()
今日优化测试
清空表,重新测试一下
邮箱号重复注册,这里虽然能捕获异常了,但是返参结构跟我们预期的不一样,我们下期继续优化
邮箱号为空,返回结构还是跟预期不一样,emmmm下次继续优化
总结
惯例,先来总结一下已经优化的都点:
- 抛异常时,没有处理,直接服务器错误了 [✓]
- schema校验不通过时,返参太难看了
- 初始化建表时,需要在
main.py文件引入,不太方便 - 返参没有统一的格式 [✓]
- 编写UserDao时,需要手动try...except```比较繁琐... [✓]
- user表的密码明文存储,不太安全 [✓]
- 注册router时,需要一个个include_router,太麻烦了
- ...
好了,今天先到这里了,我们下期见哈~
- 项目地址