• 第二章 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/

    作者:闫世成

    出处:http://cnblogs.com/yanshicheng

    联系:yans121@sina.com

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,如有问题或建议,请多多赐教,非常感谢。
  • 相关阅读:
    Spring导出可以运行的jar包
    sed 多行处理详细总结
    Shell获取某目录下所有文件夹的名称
    linux 删除换行符
    linux 切分文件
    jdbctemplate 获取数据表结构的方法&注意事项
    linux 使用ifstat查看网络使用情况
    postgresql 函数获取多个字段的数字大小值
    vim 正则替换功能
    jstl 格式化
  • 原文地址:https://www.cnblogs.com/yanshicheng/p/14805723.html
Copyright © 2020-2023  润新知