第二章 View的编写

前言

  基于 ModelViewSet 来写各个试图, 编写逻辑按照Mode开始.

TableClassify

  这个表就是前面将到的分类表, 也是整个项目的入口.

  这个表基本上是比较简单的, 此表设计为二级表, 即有主分类, 主分类下才是真正实际应用的表.如下图

新增数据

  新增数据主要关注 PID 字段, 如果上传 PID PID 必须是存在的且它的 PID Null.

  • API_URL
    • http://127.0.0.1:8000/api/v1/cmdb/table-classify/ 
  • 上传数据格式

    • {
          "name": "服务器",
          "alias": "server",
          "remark": "服务器类型表主类",
          "pid": ""
      }
  • 数据返回
 1 {
 2     "code": 0,
 3     "data": {
 4         "id": 1,
 5         "create_time": "2021-05-24 19:08:20",
 6         "update_time": "2021-05-24 19:08:20",
 7         "remark": "服务器类型表主类",
 8         "is_deleted": false,
 9         "name": "服务器",
10         "alias": "server",
11         "is_forbid_bind": false,
12         "pid": null
13     },
14     "message": null
15 }
View Code
  • 试图代码
 1     def create(self, request, *args, **kwargs):
 2         data = request.data
 3         pid = data.get('pid')
 4 
 5         # 如果新建数据存在PID
 6         if pid:
 7 
 8             # 查询 id = pid 的实例, 如果实例的PID不为Null则返回错误
 9             if OperateInstance.get_table_classify(data['pid']).pid:
10                 return json_error_response(f'指定的pid:({data["pid"]}) 不是主类型模型表.')
11         return super(TableClassifyViewSet, self).create(request, *args, **kwargs)

修改数据

  新增数据主要关注 PID 字段, 

  1. 如果 修改的数据为主类型, 则需要判断此表下有没有分类表, 如果有则禁止修改.
  2. 判断要修改的目标PID是否为主类型表, 判断方法, 取到 id = pid 的实例, 实例.pid 为空则是主分类.
  • API_URL
    • http://127.0.0.1:8000/api/v1/cmdb/table-classify/ID/
  • 上传数据格式

    • {
          "name": "服务器",
          "alias": "server",
          "remark": "服务器类型表主类",
          "pid": ""
      }
  • 数据返回
 1 {
 2     "code": 0,
 3     "data": {
 4         "id": 4,
 5         "create_time": "2021-05-24 19:15:20",
 6         "update_time": "2021-05-24 19:16:12",
 7         "remark": "物理机类型表",
 8         "is_deleted": false,
 9         "name": "物理网卡1",
10         "alias": "network",
11         "is_forbid_bind": false,
12         "pid": 1
13     },
14     "message": null
15 }
View Code
  • 试图代码
 1     def update(self, request, *args, **kwargs):
 2         instance = self.get_object()
 3         pid = request.data.get('pid')
 4         # 判断是否存在PID
 5         if pid:
 6             # 查询 pid = instance.id 的表, 如果存在则报错.
 7             if OperateInstance.get_children_table_classify(instance.id):
 8                 return json_error_response('无法修改, 此类型表存在子分类表.')
 9             # 获取要要指定为主类的实例, 并判断是否为主类 也就是 PID == Null
10             parent_table_classify = OperateInstance.get_table_classify(pid)
11             if not parent_table_classify or parent_table_classify.pid:
12                 return json_error_response('指定的 pid 不存在或者不是主分类表.')
13         return super(TableClassifyViewSet, self).update(request, *args, **kwargs)

表关系绑定

  表关系绑定这里用到了 TableRelation 表来确定绑定管理,

字段说明:

  1. TableClassify 的 is_forbid_bind, 这个值用来判断是否可以绑定, 如果设置为True, 其他的表就无法跟此表绑定.
  2. TableRelation 的  parent_table, 主表ID.
  3. TableRelation 的  child_table, 子表ID
  4. TableRelation 的  is_foreign_key, 表示绑定之后数据的对应关系, 为True 则是一对多, 为 False 则是 一对一.

验证逻辑:

  1. 验证 上传的 parent_table_id 和 child_table_id 是否存在 TableClassify 实例. 并且不是 主分类表.
  2. 验证 parent_table_id 和 child_table_id 实例  is_forbid_bind 如果为 True 则禁止进行数据绑定.
  3. 验证 parent_table_id 和 child_table_id 实例 有没有自己的字段表, 如果没有禁止绑定, 这个规则可以删掉, 逻辑问题.
  • URL
    • http://127.0.0.1:8000/api/v1/cmdb/table-classify/relation/
  • 数据上传格式
1 {
2     "parent_table_id": 2,
3     "child_table_id": 3,
4     "is_foreign_key": false,
5     "is_forbid_bind": true
6 }
  • 数据返回格式
{
    "code": 0,
    "data": "关联成功",
    "message": null
}
View Code
  • 试图代码
 1     @action(methods=['post'], detail=False)
 2     def relation(self, request, *args, **kwargs):
 3         data = request.data
 4         parent_table_id = data['parent_table_id']
 5         child_table_id = data['child_table_id']
 6         if not parent_table_id or not child_table_id:
 7             return json_error_response('parent_table_id and child_table_id 是必传参数.')
 8 
 9         parent_classify = OperateInstance.get_table_classify(parent_table_id)
10         child_classify = OperateInstance.get_table_classify(child_table_id)
11 
12         # 验证表是否存在
13         if not parent_classify or not child_classify:
14             return json_error_response('parent分类表或者child分类表不存在')
15 
16         # 验证 有主分类表
17         if not parent_classify.pid or not child_classify.pid:
18             return json_error_response('parent分类表或者child分类表是主分类表, 不允许进行绑定操作.')
19 
20         # 验证 是否禁止绑定.
21         if parent_classify.is_forbid_bind or child_classify.is_forbid_bind:
22             return json_error_response('parent分类表或者child分类表,禁止绑定操作.')
23 
24         # 验证是否存在字段表
25         parent_field = OperateInstance.get_table_field(parent_table_id)
26         child_field = OperateInstance.get_table_field(child_table_id)
27         if not parent_field or not child_field:
28             return json_error_response('parent类型表或者child类型表没有字段表')
29 
30         table_relation_obj = TableRelation.objects.create(parent_table_id=parent_table_id,
31                                                           child_table_id=child_table_id,
32                                                           is_foreign_key=data.get('is_foreign_key'))
33         table_relation_obj.save()
34 
35         if request.data.get('is_forbid_bind'):
36             child_classify.is_forbid_bind = True
37             child_classify.save()
38 
39         return json_ok_response('关联成功')

表关系解绑

  • 验证逻辑
    • 确定存在绑定记录
    • 清理资产绑定记录
    • child_table is_forbid_bind 字段如果为True 修改为False.

  • URL
    • http://127.0.0.1:8000/api/v1/cmdb/table-classify/un-relation/
  • 上传数据格式
{
    "parent_table_id": 2,
    "child_table_id": 7
}
  • 数据返回格式
{
    "code": 0,
    "data": "解除关联成功",
    "message": null
}
  • 试图代码
 1     @action(methods=['post'], detail=False, url_path='un-relation')
 2     def un_relation(self, request, *args, **kwargs):
 3         data = request.data
 4 
 5         parent_table_id = data['parent_table_id']
 6         child_table_id = data['child_table_id']
 7         if not parent_table_id or not child_table_id:
 8             return json_error_response('parent_table_id and child_table_id 是必传参数.')
 9 
10         classify_relation_obj = OperateInstance.get_table_relation(parent_table_id, child_table_id)
11         if not classify_relation_obj:
12             return json_error_response(
13                 f'找不到parent_table_id为:{parent_table_id}, child_table_id为: {child_table_id} 关系记录')
14 
15         # 找到绑定资产记录并删除
16         asset_relation_all = OperateInstance.get_asset_relation(classify_relation_obj)
17         if asset_relation_all:
18             for instance in asset_relation_all:
19                 instance.delete()
20 
21         classify_relation_obj.delete()
22 
23         # 修改 child_classify_obj 的值
24         child_classify_obj = OperateInstance.get_table_classify(child_table_id)
25         if child_classify_obj.is_forbid_bind:
26             child_classify_obj.is_forbid_bind = False
27             child_classify_obj.save()
28 
29         return json_ok_response('解除关联成功')

删除数据

  • 验证逻辑
  • URL
    • http://127.0.0.1:8000/api/v1/cmdb/table-field/ | http://127.0.0.1:8000/api/v1/cmdb/table-field/ID/
  • 上传数据格式
  • 数据返回格式
  • 试图代码

查询数据

  • 验证逻辑
    • 查看数据同时要返回字段表的 fields, rules
  • URL
    • http://127.0.0.1:8000/api/v1/cmdb/table-classify/
  • 数据返回格式
{
    "code": 0,
    "data": [
        {
            "id": 1,
            "create_time": "2021-05-24 19:08:20",
            "update_time": "2021-05-24 19:08:20",
            "remark": "服务器类型表主类",
            "is_deleted": false,
            "name": "服务器",
            "alias": "server",
            "is_forbid_bind": false,
            "pid": null,
            "fields": null,
            "rules": null
        },
        {
            "id": 2,
            "create_time": "2021-05-24 19:14:25",
            "update_time": "2021-05-24 19:14:25",
            "remark": "物理机类型表",
            "is_deleted": false,
            "name": "物理机",
            "alias": "Physical",
            "is_forbid_bind": false,
            "pid": 1,
            "fields": {
                "board_sn": {
                    "name": "主板SN号",
                    "order": 5
                },
                "hostname": {
                    "guid": true,
                    "name": "主机名",
                    "order": 0
                },
                "cpu_count": {
                    "name": "逻辑CPU",
                    "order": 5
                },
                "cpu_model": {
                    "name": "cpu_型号",
                    "order": 10
                },
                "manage_ip": {
                    "name": "管理IP",
                    "order": 1
                },
                "os_version": {
                    "name": "系统版本",
                    "order": 3
                },
                "board_model": {
                    "name": "型号",
                    "order": 7
                },
                "os_platform": {
                    "name": "操作系统",
                    "order": 2
                },
                "device_status": {
                    "name": "设备状态",
                    "order": 4
                },
                "board_manufacturer": {
                    "name": "制造商",
                    "order": 6
                },
                "cpu_physical_count": {
                    "name": "物理CPU",
                    "order": 6
                }
            },
            "rules": {
                "board_sn": {
                    "lens": 64,
                    "type": "Str"
                },
                "hostname": {
                    "lens": 46,
                    "type": "Str",
                    "unique": true,
                    "not_null": false
                },
                "cpu_count": {
                    "max": 130,
                    "min": 1,
                    "type": "Int"
                },
                "cpu_model": {
                    "lens": 64,
                    "type": "Str"
                },
                "manage_ip": {
                    "type": "IP",
                    "prefix": "172.16.0.",
                    "unique": true
                },
                "os_version": {
                    "lens": 64,
                    "type": "Str"
                },
                "board_model": {
                    "lens": 64,
                    "type": "Str"
                },
                "os_platform": {
                    "lens": 64,
                    "type": "Str"
                },
                "device_status": {
                    "type": "Choice",
                    "choice": [
                        "上线",
                        "下线",
                        "离线"
                    ],
                    "default": 0
                },
                "board_manufacturer": {
                    "lens": 64,
                    "type": "Str"
                },
                "cpu_physical_count": {
                    "max": 64,
                    "min": 1,
                    "type": "Int"
                }
            }
        },
        {
            "id": 3,
            "create_time": "2021-05-24 19:15:05",
            "update_time": "2021-05-24 22:20:01",
            "remark": "物理机类型表",
            "is_deleted": false,
            "name": "物理磁盘",
            "alias": "disk",
            "is_forbid_bind": true,
            "pid": 1,
            "fields": {
                "slot": {
                    "guid": true,
                    "name": "槽位",
                    "order": 0
                },
                "model": {
                    "name": "型号",
                    "order": 1
                },
                "pd_type": {
                    "name": "类别",
                    "order": 2
                },
                "capacity": {
                    "name": "容量",
                    "order": 2
                }
            },
            "rules": {
                "slot": {
                    "lens": 64,
                    "type": "Str",
                    "unique": true
                },
                "model": {
                    "lens": 64,
                    "type": "Str"
                },
                "pd_type": {
                    "lens": 64,
                    "type": "Str"
                },
                "capacity": {
                    "lens": 64,
                    "type": "Str"
                }
            }
        },
        {
            "id": 4,
            "create_time": "2021-05-24 19:15:20",
            "update_time": "2021-05-24 22:23:05",
            "remark": "物理机类型表",
            "is_deleted": false,
            "name": "物理网卡",
            "alias": "network",
            "is_forbid_bind": true,
            "pid": 1,
            "fields": {
                "up": {
                    "name": "网卡状态",
                    "order": 5
                },
                "name": {
                    "guid": true,
                    "name": "网卡名",
                    "order": 0
                },
                "hwaddr": {
                    "name": "Mac地址",
                    "order": 4
                },
                "ipaddr": {
                    "name": "IP地址",
                    "order": 1
                },
                "gateway": {
                    "name": "网关",
                    "order": 3
                },
                "network": {
                    "name": "子网掩码",
                    "order": 2
                }
            },
            "rules": {
                "up": {
                    "lens": 64,
                    "type": "Str"
                },
                "name": {
                    "lens": 46,
                    "type": "Str",
                    "unique": true
                },
                "hwaddr": {
                    "lens": 120,
                    "type": "Str"
                },
                "ipaddr": {
                    "type": "IP",
                    "unique": true,
                    "not_null": true
                },
                "gateway": {
                    "type": "IP"
                },
                "network": {
                    "lens": 64,
                    "type": "Str"
                }
            }
        },
        {
            "id": 5,
            "create_time": "2021-05-24 22:06:59",
            "update_time": "2021-05-24 22:23:11",
            "remark": "存放物理机内存",
            "is_deleted": false,
            "name": "物理内存",
            "alias": "memory",
            "is_forbid_bind": true,
            "pid": 1,
            "fields": {
                "sn": {
                    "name": "SN号",
                    "order": 4
                },
                "slot": {
                    "guid": true,
                    "name": "槽位",
                    "order": 0
                },
                "model": {
                    "name": "型号",
                    "order": 2
                },
                "speed": {
                    "name": "速率",
                    "order": 5
                },
                "capacity": {
                    "name": "容量",
                    "order": 3
                },
                "manufacturer": {
                    "name": "制造商",
                    "order": 1
                }
            },
            "rules": {
                "sn": {
                    "lens": 64,
                    "type": "Str"
                },
                "slot": {
                    "lens": 64,
                    "type": "Str",
                    "unique": true
                },
                "model": {
                    "lens": 64,
                    "type": "Str"
                },
                "speed": {
                    "lens": 64,
                    "type": "Str"
                },
                "capacity": {
                    "lens": 64,
                    "type": "Str"
                },
                "manufacturer": {
                    "lens": 64,
                    "type": "Str"
                }
            }
        },
        {
            "id": 6,
            "create_time": "2021-05-24 22:08:53",
            "update_time": "2021-05-24 22:08:53",
            "remark": "存放通用记录",
            "is_deleted": false,
            "name": "通用类",
            "alias": "general",
            "is_forbid_bind": false,
            "pid": null,
            "fields": null,
            "rules": null
        },
        {
            "id": 7,
            "create_time": "2021-05-24 22:09:25",
            "update_time": "2021-05-25 00:51:53",
            "remark": "设备资产标签",
            "is_deleted": false,
            "name": "标签",
            "alias": "label",
            "is_forbid_bind": false,
            "pid": 6,
            "fields": {
                "name": {
                    "guid": true,
                    "name": "标签名",
                    "order": 0
                }
            },
            "rules": {
                "name": {
                    "lens": 64,
                    "type": "Str",
                    "unique": true
                }
            }
        }
    ],
    "message": null
}
View Code
  • 无试图代码, serializers 代码如下
class TableClassifySerializer(serializers.ModelSerializer):
    class Meta:
        model = TableClassify
        fields = '__all__'

    def to_representation(self, instance):
        representation = super(TableClassifySerializer, self).to_representation(instance)
        representation['fields'] = TableFieldSerializer(instance.fields).data['fields'] if hasattr(instance,
                                                                                                   'fields') else None
        representation['rules'] = TableFieldSerializer(instance.fields).data['rules'] if hasattr(instance,
                                                                                                 'fields') else None
        return representation

 

TableField

  字段表, 主要用于类型表的字段存储, 以及校验规则.

字段说明:

  • fields 字段
 1 "fields": {
 2     "hostname": {
 3         "name": "主机名",      # key 字段, val 是中文, 前端展示以及后端校验使用. 
 4         "guid": true,          # 全局唯一, 用来标识唯一Key的. 只可以出现一次
 5         "order": 0               # 排序 ID, 前端使用
 6     },
 7     "manage_ip": {
 8         "name": "管理IP",
 9         "order": 1
10     }
11     ... 
12 }
  • rules
 1 "rules": {
 2     "hostname": {               # key 跟 fields 字段 key 一一对应.
 3         "type": "Str",
 4         "lens": 46,                # 限制属性可选
 5         "unique": true,            # 如果 fields 中设置了全局唯一 key.必须这是 unique 为 True
 6         "not_null": false
 7     },
 8     "manage_ip": {
 9         "type": "IP",
10         "unique": true,
11         "prefix": "172.16.0."
12     }
13     ...
14 }

现支持的类型及属性:

  • 类型
    • ["Str", "Int", "Choice", "IP"]
  • 属性
    • ["default", "unique", "not_null", "lens", "choice", "prefix", "max", "min"]

新增数据

  • 验证逻辑
    • 1. 如果分类表是主分类表禁止绑定.
    • 2. 上传数据验证, 使用 check_fields 
  • URL
    • http://127.0.0.1:8000/api/v1/cmdb/table-field/
  • 数据上传格式
{
    "remark": "",
    "table_classify": 2,
    "fields": {
        "hostname": {
            "name": "主机名",
            "guid": true,
            "order": 0
        },
        "manage_ip": {
            "name": "管理IP",
            "order": 1
        },
        "os_platform": {
            "name": "操作系统",
            "order": 2
        },
        "os_version": {
            "name": "系统版本",
            "order": 3
        },
        "device_status": {
            "name": "设备状态",
            "order": 4
        },
        "cpu_count": {
            "name": "逻辑CPU",
            "order": 5
        },
        "cpu_physical_count": {
            "name": "物理CPU",
            "order": 6
        },
        "cpu_model":{
            "name":  "cpu_型号",
            "order": 10
        },
        "board_sn": {
            "name": "主板SN号",
            "order": 5
        },
        "board_manufacturer": {
            "name": "制造商",
            "order": 6
        },
        "board_model": {
            "name": "型号",
            "order": 7
        }
        
    },
    "rules": {
        "hostname": {
            "type": "Str",
            "lens": 46,
            "unique": true,
            "not_null": false
        },
        "manage_ip": {
            "type": "IP",
            "unique": true,
            "prefix": "172.16.0."
        },
        "os_platform": {
            "type": "Str",
            "lens": 64
        },
        "os_version": {
            "type": "Str",
            "lens": 64
        },
        "device_status": {
            "type": "Choice",
            "choice": ["上线", "下线", "离线"],
            "default": 0
        },
        "cpu_count": {
            "type": "Int",
            "max": 130,
            "min": 1
        },
        "cpu_physical_count": {
            "type": "Int",
            "max": 64,
            "min": 1
        },
        "cpu_model":{
            "type": "Str",
            "lens": 64
        },
        "board_sn": {
            "type": "Str",
            "lens": 64
        },
        "board_manufacturer": {
            "type": "Str",
            "lens": 64
        },
        "board_model": {
            "type": "Str",
            "lens": 64
        }
    }
}
物理机表
{
    "remark": "",
    "table_classify": 4,
    "fields": {
        "name": 
            {
                "name": "网卡名",
                "guid": true,
                "order": 0
            },
        "ipaddr": 
            {
                "name": "IP地址",
                "order": 1
            },
        "network": 
            {
                "name": "子网掩码",
                "order": 2
            },
        "gateway": 
            {
                "name": "网关",
                "order": 3
            },
        "hwaddr": 
            {
                "name": "Mac地址",
                "order": 4
            },
        "up": 
            {
                "name": "网卡状态",
                "order": 5
            }
    },
    "rules": {
        "name": {
            "type": "Str",
            "lens": 46,
            "unique": true
        },
        "ipaddr": {
            "type": "IP",
            "unique": true,
            "not_null": true
        },
        "network": {
            "type": "Str",
            "lens": 64
        },
        "gateway": {
            "type": "IP"
        },
        "hwaddr": {
            "type": "Str",
            "lens": 120
        },
        "up": {
            "type": "Str",
            "lens": 64
        }
    }
}
网卡表
{
    "remark": "",
    "table_classify": 3,
    "fields": {
        "slot": {
             "name": "槽位",
            "guid": true,
            "order": 0
        },
        "model": {
            "name": "型号",
            "order": 1
        },
        "capacity":{
            "name": "容量",
            "order": 2
        },
        "pd_type": {
            "name": "类别",
            "order": 2
        }
    },
    "rules": {
        "slot": {
            "type": "Str",
            "lens": 64,
            "unique": true
        },
        "model": {
            "type": "Str",
            "lens": 64
        },
        "capacity":{
            "type": "Str",
            "lens": 64
        },
        "pd_type": {
            "type": "Str",
            "lens": 64
        }
    }
}
磁盘表
{
    "remark": "",
    "table_classify": 5,
    "fields": {
        "slot": {
             "name": "槽位",
            "guid": true,
            "order": 0
        },
        "manufacturer": {
            "name": "制造商",
            "order": 1
        },
        "model":{
            "name": "型号",
            "order": 2
        },
        "capacity": {
            "name": "容量",
            "order": 3
        },
        "sn":{
            "name": "SN号",
            "order": 4
        },
        "speed": {
            "name": "速率",
            "order": 5
        }
        
    },
    "rules": {
        "slot": {
            "type": "Str",
            "lens": 64,
            "unique": true
        },
        "manufacturer": {
            "type": "Str",
            "lens": 64
        },
        "model":{
            "type": "Str",
            "lens": 64
        },
        "capacity": {
            "type": "Str",
            "lens": 64
        },
        "sn": {
               "type": "Str",
            "lens": 64 
        },
        "speed": {
               "type": "Str",
            "lens": 64 
        }
    }
}
内存表
{
    "remark": "",
    "table_classify": 7,
    "fields": {
        "name": {
             "name": "标签名",
            "guid": true,
            "order": 0
        }
        
    },
    "rules": {
        "name": {
            "type": "Str",
            "lens": 64,
            "unique": true
        }
    }
}
标签表
  • 数据返回格式
 1 {
 2     "code": 0,
 3     "data": {
 4         "id": 5,
 5         "fields": {
 6             "name": {
 7                 "name": "标签名",
 8                 "guid": true,
 9                 "order": 0
10             }
11         },
12         "create_time": "2021-05-24 22:10:51",
13         "update_time": "2021-05-24 22:10:51",
14         "remark": "",
15         "is_deleted": false,
16         "rules": {
17             "name": {
18                 "type": "Str",
19                 "lens": 64,
20                 "unique": true
21             }
22         },
23         "table_classify": 7,
24         "parent_table_classify": "通用类"
25     },
26     "message": null
27 }
View Code
  • 试图代码
1     def create(self, request, *args, **kwargs):
2         check_field(request.data)
3         table_classify_obj = OperateInstance.get_table_classify(request.data['table_classify'])
4 
5         # 判断 table_classify实例是否存在并且不是主分类
6         if not table_classify_obj or not table_classify_obj.pid:
7             return json_error_response('table_classify实例不存在或者table_classify实例为主分类,主分类不允许创建字段表.')
8         return super(TableFieldViewSet, self).create(request, *args, **kwargs)

修改数据

  • 验证逻辑
    • 如果已经有数据不允许更换分类表.
    • 更换分配表判断分类表是否为主分类.
  • 其他验证规则同创建保持一致
  • URL
    • http://127.0.0.1:8000/api/v1/cmdb/table-field/ID/
  • 试图代码
    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        data = request.data

        # 判断如果更换 table_classify_id 当前 instance 是否存在资产
        if instance.table_classify.id != data['table_classify'] and OperateInstance.get_all_asset(
                instance.table_classify.id):
            return json_error_response('分类表已经存在资产, 字段表不允许更换主类.')

        # 判断更换的 table_classify 是否是 主分类表
        if not OperateInstance.get_table_classify(data['table_classify']).pid:
            return json_error_response('指定的分类表为主分类,主分类无法设置表字段.')

        # 检查数据
        check_field(data)

        return super(TableFieldViewSet, self).update(self, request, *args, **kwargs)

查看数据

  • 验证逻辑
  • URL
    • http://127.0.0.1:8000/api/v1/cmdb/table-field/ | http://127.0.0.1:8000/api/v1/cmdb/table-field/ID/
  • 上传数据格式
  • 数据返回格式
  • 试图代码

删除数据

 

  • 验证逻辑
  • URL
    • http://127.0.0.1:8000/api/v1/cmdb/table-field/ | http://127.0.0.1:8000/api/v1/cmdb/table-field/ID/
  • 上传数据格式
  • 数据返回格式
  • 试图代码

 TableData

    这个表主要是用于分类表数据的存储.

新增数据

  • 验证逻辑
    • 根据分类表字段规则进行校验数据, check_data
  • URL
    • http://127.0.0.1:8000/api/v1/cmdb/table-data/
  • 上传数据格式
 1 {
 2     "remark": "",
 3     "table_classify": 2,
 4     "data":{
 5         "hostname": "ops107.devops.cc",
 6         "manage_ip": "172.16.0.107",
 7         "os_platform":"Linux",
 8         "os_version": "Centos 7.9.2004",
 9         "device_status": "",
10         "cpu_count": "64",
11         "cpu_physical_count": 24,
12         "cpu_model":"志强 E52699 V4",
13         "board_sn": "00:34:87:ce:2f",
14         "board_manufacturer": "英特尔",
15         "board_model": "C610"
16     }
17 }
  • 数据返回格式
{
    "code": 0,
    "data": {
        "id": 7,
        "create_time": "2021-05-25 13:52:18",
        "update_time": "2021-05-25 13:52:18",
        "remark": "",
        "is_deleted": false,
        "data": {
            "hostname": "ops107.devops.cc",
            "manage_ip": "172.16.0.107",
            "os_platform": "Linux",
            "os_version": "Centos 7.9.2004",
            "device_status": 0,
            "cpu_count": 64,
            "cpu_physical_count": 24,
            "cpu_model": "志强 E52699 V4",
            "board_sn": "00:34:87:ce:2f",
            "board_manufacturer": "英特尔",
            "board_model": "C610"
        },
        "table_classify": 2,
        "parent_table_classify": "服务器",
        "field": {
            "board_sn": {
                "name": "主板SN号",
                "order": 5
            },
            "hostname": {
                "guid": true,
                "name": "主机名",
                "order": 0
            },
            "cpu_count": {
                "name": "逻辑CPU",
                "order": 5
            },
            "cpu_model": {
                "name": "cpu_型号",
                "order": 10
            },
            "manage_ip": {
                "name": "管理IP",
                "order": 1
            },
            "os_version": {
                "name": "系统版本",
                "order": 3
            },
            "board_model": {
                "name": "型号",
                "order": 7
            },
            "os_platform": {
                "name": "操作系统",
                "order": 2
            },
            "device_status": {
                "name": "设备状态",
                "order": 4
            },
            "board_manufacturer": {
                "name": "制造商",
                "order": 6
            },
            "cpu_physical_count": {
                "name": "物理CPU",
                "order": 6
            }
        },
        "children": {}
    },
    "message": null
}
View Code
  • 试图代码
 1     def create(self, request, *args, **kwargs):
 2         
 3         # 校验数据
 4         try:
 5             data = check_data(request.data, 'create')
 6         except ValueError as e:
 7             return json_error_response(f'数据校验出错: {str(e)}')
 8         
 9         serializer = self.get_serializer(data=data)
10         serializer.is_valid(raise_exception=True)
11         self.perform_create(serializer)
12         self.get_success_headers(serializer.data)
13         return json_ok_response(serializer.data)

 

修改数据

  • 验证逻辑
    • 数据创建后不可修改分类表
  • URL
    • http://127.0.0.1:8000/api/v1/cmdb/table-data/10/
  • 上传数据格式
        {
            "remark": "",
            "data": {
                "board_sn": "00:34:87:ce:2f",
                "hostname": "ops11.devops.cc",
                "cpu_count": 64,
                "cpu_model": "志强 E52699 V4",
                "manage_ip": "172.16.0.11",
                "os_version": "Centos 7.9.2004",
                "board_model": "C610",
                "os_platform": "Linux",
                "device_status": 0,
                "board_manufacturer": "英特尔",
                "cpu_physical_count": 24
            },
            "table_classify": 2
        }
  • 数据返回格式
{
    "code": 0,
    "data": {
        "id": 10,
        "create_time": "2021-05-25 13:55:00",
        "update_time": "2021-05-25 21:01:24",
        "remark": "",
        "is_deleted": false,
        "data": {
            "board_sn": "00:34:87:ce:2f",
            "hostname": "ops11.devops.cc",
            "cpu_count": 64,
            "cpu_model": "志强 E52699 V4",
            "manage_ip": "172.16.0.11",
            "os_version": "Centos 7.9.2004",
            "board_model": "C610",
            "os_platform": "Linux",
            "device_status": 0,
            "board_manufacturer": "英特尔",
            "cpu_physical_count": 24
        },
        "table_classify": 2
    },
    "message": null
}
View Code
  • 试图代码
    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        try:
            data = check_data(request.data, instance)
        except ValueError as e:
            return json_error_response(f'数据校验出错: {str(e)}')

        if data.get('table_classify') and data.get(
                'table_classify') != instance.table_classify.id:
            return json_error_response('数据不可修改类型, 如需更换请进行删除.')

        partial = kwargs.pop('partial', False)

        serializer = self.get_serializer(instance, data=data, partial=partial)
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)

        if getattr(instance, '_prefetched_objects_cache', None):
            instance._prefetched_objects_cache = {}

        return json_ok_response(serializer.data)

数据绑定

  • 验证逻辑
    • 验证有没有分类关系表 为  parent_table_id 和 child_table_id
    • 判断分类表有没有响应的资产数据, 即查询条件  table_classify_id = parent_table_id  & id = parent_asset_id
    • 如果 关系绑定实例的  is_foreign_key == False, 需要判断子资产有没有被其他资产绑定过.
  • URL
    • http://127.0.0.1:8000/api/v1/cmdb/table-field/ | http://127.0.0.1:8000/api/v1/cmdb/table-field/ID/
  • 上传数据格式
{
    "parent_table_id": 2,
    "child_table_id": 3,
    "parent_asset_id": 2,
    "child_asset_id": 8
}
  • 数据返回格式
{
    "code": 0,
    "data": "资产数据绑定成功",
    "message": null
}
  • 试图代码
 1     @action(methods=['post'], detail=False)
 2     def relation(self, request, *args, **kwargs):
 3         data = request.data
 4 
 5         parent_table_id = data['parent_table_id']
 6         child_table_id = data['child_table_id']
 7         table_relation_obj = OperateInstance.get_table_relation(parent_table_id, child_table_id)
 8         # 判断分类关系绑定表是否存在
 9         if not table_relation_obj:
10             return json_error_response('未查询到分类关系绑定表, 请先进行绑定在进行资产绑定操作.')
11 
12         parent_asset_obj = OperateInstance.get_classify_asset(data['parent_asset_id'], parent_table_id)
13         child_asset_obj = OperateInstance.get_classify_asset(data['child_asset_id'], child_table_id)
14 
15         # 判断资产是否存在
16         if not parent_asset_obj or not child_asset_obj:
17             return json_error_response('资产数据未查询到.')
18 
19         # 判断是否为 OneToOne 如果是则判断是否存在绑定记录
20         if not table_relation_obj.is_foreign_key:
21             print('1111111111111')
22             asset_relation_obj = OperateInstance.get_child_asset_relation(table_relation_obj.id, data['child_asset_id'])
23 
24             if asset_relation_obj:
25                 return json_error_response('类型表关联模式为: OneToOne, 子资产数据已经被绑定无法进行二次绑定.')
26 
27         try:
28             new_asset_relation = AssetsRelation.objects.create(parent_asset=parent_asset_obj,
29                                                                child_asset=child_asset_obj,
30                                                                table_relation=table_relation_obj)
31             new_asset_relation.save()
32         except Exception as e:
33             return json_error_response(f'数据创建出错: {str(e)}')
34         return json_ok_response('资产数据绑定成功')

数据解绑

  • 验证逻辑
  • URL
    • http://127.0.0.1:8000/api/v1/cmdb/table-field/ | http://127.0.0.1:8000/api/v1/cmdb/table-field/ID/
  • 上传数据格式
  • 数据返回格式
  • 试图代码

数据删除

  • 验证逻辑
  • URL
    • http://127.0.0.1:8000/api/v1/cmdb/table-field/ | http://127.0.0.1:8000/api/v1/cmdb/table-field/ID/
  • 上传数据格式
  • 数据返回格式
  • 试图代码

数据查看

  • 验证逻辑
  • URL
    • http://127.0.0.1:8000/api/v1/cmdb/table-field/ | http://127.0.0.1:8000/api/v1/cmdb/table-field/ID/
  • 上传数据格式
  • 数据返回格式
  • 试图代码

 

 

 

 

 

 

 

 

http://127.0.0.1:8000/api/v1/cmdb/table-field/1/

posted @ 2021-05-25 21:41  闫世成  阅读(90)  评论(0编辑  收藏  举报