
啊胡
2022/10/04阅读:21主题:绿意
16 接口自动化 接口管理模块开发(五)
别人写的平台再垃圾,也是用来淘汰你的。
Python环境没有的,请自行安装,本教程采用的是python 3.9。
Django官网 https://www.djangoproject.com/
Node环境没有的,请自行安装,本教程采用的是node v17.6.0。
Vue.js官网 https://cn.vuejs.org/
首先来解决的上章遗留的问题,如何在DRF中自定义接口。其实直接使用Django的方案来编写接口一样可以达到目的,但是从《Django如何快速开发RESTful风格的接口?》中源码分析部分可以知道,DRF为开发接口提供了更方便的能力,因此本章还是采用DRF的方案来自定义接口。
DRF中自定义接口
这个接口的主要功能是在查询分类时,同时查询接口列表。
-
首先在后端项目 main/views.py
中定义一个新的接口继承DRF的APIView
。然后定义get方法用来处理get请求。
class CategoryApiView(APIView):
def get(self,request):
pass
-
然后编写逻辑部分 -
如果没有请求参数,即查询没有父分类的分类列表和没有分类的接口列表 -
如果存在请求参数category,即查询有父分类category的分类列表和有分类category的接口列表
-
class CategoryApiView(APIView):
def get(self, request):
category = None
if "category" in request.GET:
category = request.GET['category']
if category:
query_set = Category.objects.filter(parent_category=category)
category_data = CategorySerializer(query_set, many=True).data
query_set = Api.objects.filter(category=category)
api_data = ApiSerializer(query_set, many=True).data
else:
query_set = Category.objects.filter(parent_category__isnull=True)
category_data = CategorySerializer(query_set, many=True).data
query_set = Api.objects.filter(category__isnull=True)
api_data = ApiSerializer(query_set, many=True).data
return Response(category_data + api_data)
-
在 main/urls.py
中定义接口路由
urlpatterns = [
...
path('categorie_apis/', CategoryApiView.as_view())
]
重启项目,查看swagger页面,可以看到新增了一个接口。

后端项目定义完成后,接下来就是前端调用,有两个地方需要进行替换:
-
第一个地方是进入接口管理页面,需要调用接口查询没有一级分类列表和没有分类的接口列表
const queryCategories = (parent_category) => {
// listCategoryApi(parent_category).then((res) => {
// treeData.value = res;
// });
listCategoryApiApi(parent_category).then((res) => {
treeData.value = res;
});
};
重启前端项目,刷新页面,可以看到一级分类以及没有分类的接口都被查询出来了。

-
第二个地方是点击树形结构进行加载,需要将节点ID作为查询参数,调用接口查询指定分类ID下的分类列表和接口列表。
const loadData = (treeNode) => {
return new Promise((resolve) => {
if (treeNode.dataRef.children) {
resolve();
return;
}
if (treeNode.dataRef.type === "collection") {
// 分类下查询子分类和接口
// listCategoryApi(treeNode.dataRef.id).then((res) => {
// let children = res;
// listApiApi(treeNode.dataRef.id).then((res) => {
// children = children.concat(res);
// treeNode.dataRef.children = children;
// treeData.value = [...treeData.value];
// resolve();
// });
// });
listCategoryApiApi(treeNode.dataRef.id).then((res) => {
treeNode.dataRef.children = res;
treeData.value = [...treeData.value];
resolve();
});
} else {
// TODO:接口需要查询用例
resolve();
}
});
};
重启前端项目,刷新页面,点击「分类一」的展开按钮,可以看到子分类和分类下的接口都被查询出来了。
接口管理模块开发(五)
上节已经完成了在分类下新增不带参数的GET请求,并且保存成功,本节将完成在分类下新增带参数的GET请求(包括请求参数和请求头)。
前端组件完善
前面我们定义了TableForm
组件,将ATable进行了封装。 存在一个问题是当没有参数时,没有新增按钮,因此需要对于
TableForm
组件中的ATable再次进行改造,将无数据时的样式替换掉。

请求参数和请求头保存
组件完善后,首先来处理请求参数和请求头,因为请求参数和请求头都是单独的子组件,在页面上填写的数据也都是保存在子组件的变量中,因此点击父组件【Save】时,父组件要先获取到子组件的值。
-
在 ApiHeader
定义一个方法,用于返回initData,并且将方法暴露出来供父组件使用。
<template>
<div class="api-header">
<table-form :initData="initData"></table-form>
</div>
</template>
<script setup>
import { ref, defineExpose } from "vue";
import TableForm from "@/components/TableForm.vue";
const initData = ref([]);
const getData = () => {
return initData.value;
};
// 暴露方法,以供父组件进行调用
defineExpose({
getData,
});
</script>
-
在 ApiListContent
中引用子组件ApiHeader
时,子组件定义ref属性,并且进行变量声明。

-
点击 ApiListContent
中的【Save】按钮时,通过定义的ref变量调用ApiHeader
的方法获取数据。
const saveApi = () => {
if (props.category_id !== "") {
formState.value.category = props.category_id;
}
// 获取请求头
if (apiHeader.value) {
formState.value.headers = JSON.stringify(apiHeader.value.getData());
}
addApiApi(formState.value).then(() => {
message.success("保存成功");
});
};
获取请求参数和请求头是同样的操作,将不再赘述。
重启项目,刷新页面,在分类一下选择新增接口,填写接口的请求信息,点击【Save】按钮。可以看到接口请求中已经有请求参数和请求头。

检查数据库可以看到数据已经保存成功。

本章到这里就结束来,下章接着讲带请求体的POST请求如何保存。
作者介绍
