pity接口自动化测试平台开发文档 测试平台系列 (19) 编写项目的增删改查接口和页面 (1)
回顾
上一节咱们定制好了简单的权限系统,也设计了相关的表概念。但是表只有对应的 model,并没有编写实际的操作接口,所以今天我们来完善他们!
上次我们编写的TestCase表存在一点问题,首先是没有params
字段,也没有body
字段,当然可能还缺少很多字段,我们可以在后续的开发过程中陆续补充
。
在 dao/init.py 加入新创建的表
修改 TestCase 表
编写项目和项目角色的增删改查接口
首先咱们明确一个要求,因为项目有公有和私有的概念,所以对于用户能看到的项目应该是这样的逻辑:
- 普通用户
能看到公有项目
和私有项目(用户在该成员中,成员或创建者)
- 管理员
能看到所有项目
由于我们需要通过用户id拿到对应所属的project,所以我们先编写project_role相关接口
编写 app/dao/project/ProjectRoleDao.py
from app.models import db
from app.models.project_role import ProjectRole
from app.utils.logger import Log
class ProjectRoleDao(object):
log = Log("ProjectRoleDao")
@staticmethod
def list_project_by_user(user_id):
"""
通过user_id获取项目列表
:param user_id:
:return:
"""
try:
projects = ProjectRole.query.filter_by(user_id=user_id, deleted_at=None).all()
return [p.id for p in projects], None
except Exception as e:
ProjectRoleDao.log.error(f"查询用户: {user_id}项目失败, {e}")
return [], f"查询项目失败, {e}"
@staticmethod
def add_project_role(user_id, project_id, project_role, user):
"""
为项目添加用户
:param user_id: 用户id
:param project_id: 项目id
:param project_role: 用户角色
:param user: 创建人
:return:
"""
try:
role = ProjectRole.query.filter_by(user_id=user_id, project_id=project_id, project_role=project_role,
deleted_at=None).first()
if role is not None:
# 说明角色已经存在了
return "该用户已存在"
role = ProjectRole(user_id, project_id, project_role, user)
db.session.add(role)
db.session.commit()
except Exception as e:
ProjectRoleDao.log.error(f"添加项目用户失败, {e}")
return f"添加项目用户失败, {e}"
return None
这边暂时编写了 2 个接口,1 个是通过用户获取到用户的项目,另一个是为项目添加用户,代码很简单,也写了一些注释。由于暂时我们需要快速做一个展示,所以暂时提供,增和查功能即可
,后续的接口再慢慢补充。
编写 app/dao/project/ProjectRole.py
由于我们已经可以通过 user_id 获取到他有权限的项目,那么接下来我们把它和共有项目做一个整合就可以了。因为 project 不可能太多,所以这边我们直接用in
操作符,先预想一下sql:
select * from project where deleted_at is null and (owner = user or project_id in (已经查出的用户项目) or private is false);
首先必须是未删除的,其次是 owner=user 的,再就是非私有或者用户有权限的。
如果对于超级管理员来说的话,那么他们对于所有项目都是可见的。
from sqlalchemy import or_
from app import pity
from app.dao.project.ProjectRoleDao import ProjectRoleDao
from app.models import db
from app.models.project import Project
from app.utils.logger import Log
class ProjectDao(object):
log = Log("ProjectDao")
@staticmethod
def list_project(user, role, page, size, name=None):
"""
查询/获取项目列表
:param user: 当前用户
:param role: 当前用户角色
:param page: 当前页码
:param size: 当前size
:param name: 项目名称
:return:
"""
try:
search = [Project.deleted_at == None]
if role != pity.config.get("ADMIN"):
project_list = ProjectRoleDao.list_project_by_user(user)
search.append(or_(Project.id in project_list, Project.owner == user, Project.private == False))
if name:
search.append(Project.name.ilike("%{}%".format(name)))
data = Project.query.filter(*search)
total = data.count()
return data.order_by(Project.created_at.desc()).paginate(page, per_page=size).items, total, None
except Exception as e:
ProjectDao.log.error(f"获取用户: {user}项目列表失败, {e}")
return 0, 0, f"获取用户: {user}项目列表失败, {e}"
@staticmethod
def add_project(name, owner, user, private):
try:
data = Project.query.filter_by(name=name, deleted_at=None).first()
if data is None:
return "项目已存在"
pr = Project(name, owner, user, private)
db.session.add(pr)
db.session.commit(pr)
except Exception as e:
ProjectDao.log.error(f"新增项目: {name}失败, {e}")
return 0, 0, f"新增项目: {name}失败, {e}"
这里重点关注list_project,里面先判断用户是不是 ADMIN,如果不是,则查询一下这个用户拥有的项目,等于说是转换了我们刚才写的 sql。
最后通过项目的创建时间进行了排序,并进行了分页并返回了项目总数,第三个参数是 error 信息。
编写具体的接口
- /project/insertProject
- /project/listProject
- /project/insertProjectRole
编写获取分页的相关方法 app/handler/page.py
from flask import request
# 默认页数和页码
PAGE = 1
SIZE = 10
class PageHandler(object):
@staticmethod
def page():
"""
获取page和size
:return:
"""
page = request.args.get("page")
if page is None or not page.isdigit():
page = PAGE
size = request.args.get("size")
if size is None or not size.isdigit():
size = SIZE
return int(page), int(size)
如果没有获取到 page/size 或者说他们不是非数字,那么我们就给个默认值。
文章是去年 4 月左右写的,由于当时还没从 go 缓过来,所以经常会有 return err 的习惯,目前的 crud 的代码也有大量重复代码。针对这点后面做了优化,也是在慢慢随着文章一起改善已有的代码。不过毕竟是业余时间完成,精力有限。大家轻拍~大家就当练习下 crud 了吧 :)