CMDB资产管理系统开发【day25】:windows客户端开发

主宰稳场 提交于 2021-01-24 13:44:51

1、目录结构

PS Y:\MadkingClient> tree /f
卷 netgame 的文件夹 PATH 列表
卷序列号为 ACE3-896E
Y:.
├─bin
│      NedStark.py
│      __init__.py
│
├─conf
│  │  settings.py
│  │  __init__.py
│  │
│  └─__pycache__
│          settings.cpython-35.pyc
│          __init__.cpython-35.pyc
│
├─core
│  │  api_token.py
│  │  HouseStark.py
│  │  info_collection.py
│  │  __init__.py
│  │
│  └─__pycache__
│          api_token.cpython-35.pyc
│          HouseStark.cpython-35.pyc
│          info_collection.cpython-35.pyc
│          __init__.cpython-35.pyc
│
├─logs
│      run_log
│      __init__.py
│
├─plugins
│  │  plugin_api.py
│  │  __init__.py
│  │
│  ├─linux
│  │  │  MegaCli
│  │  │  sysinfo.py
│  │  │  __init__.py
│  │  │
│  │  └─__pycache__
│  │          sysinfo.cpython-35.pyc
│  │          __init__.cpython-35.pyc
│  │
│  ├─windows
│  │  │  sysinfo.py
│  │  │
│  │  └─__pycache__
│  │          sysinfo.cpython-35.pyc
│  │
│  └─__pycache__
│          plugin_api.cpython-35.pyc
│          __init__.cpython-35.pyc
│
└─var
        .asset_id

PS Y:\MadkingClient>

2、安装收集windows里硬件信息的模块

安装pywin32-221

下载地址:

https://jaist.dl.sourceforge.net/project/pywin32/pywin32/Build%20221/pywin32-221.win-amd64-py3.5.exe

安装一路下一步就可以了

安装WMI

下载地址:

https://files.pythonhosted.org/packages/f6/6b/3c15ef280e2a6244ff0635f763b86fdc113654afc1192fcea8a0109f47f8/WMI-1.4.9.win32.exe

安装一路回车就可以了

python WMI模块的使用实例

https://blog.csdn.net/zmj_88888888/article/details/8700950

turer单词写错

3、如何把数据传输都服务器?

你不知道管理员什么时候审批?

让管理员知道你把数据发给他了,

1、肯定不能存在表里,
2、存到服务器内存不行,客户端一重启就不行了,

3、写到文件里可以
4、存到数据库的临时表里面

我有一条资产要发送给服务器我把数据不能存到数据库里那我存到那里呀?

答:新资产审批区,等管理员审批完了写到数据库里

客户第二次回报的数据怎样和第一次存到数据库里面的数据如何关联?

1、可以用SN号作为关联

这个是最简单的

2、可以同过自增id

之前,我在汽车之家就没有把sn当做资产唯一值

数据更新流程

1、第一次数据存到待批准区
2、当管理员资产一批准就会把资产Id返回给客户端
3、以后客户端更新就带着服务器端给的资产ID

服务器如何把资产id返回给客户端?

1、服务端无法返回因为是一个web浏览器
2、所以他只有等只有等客户端第二次链接的时候给他一个资产ID

 4、NedStark入口

#_*_coding:utf-8_*_
import os,sys,platform #for linux if platform.system() == "Windows": BASE_DIR = '\\'.join(os.path.abspath(os.path.dirname(__file__)).split('\\')[:-1]) print BASE_DIR else: BASE_DIR = '/'.join(os.path.abspath(os.path.dirname(__file__)).split('/')[:-1]) sys.path.append(BASE_DIR) from core import HouseStark if __name__ == '__main__': HouseStark.ArgvHandler(sys.argv)
#为什么叫nedstack入口文件,分析参数,手机参数,私有方法

5、HouseStark注释

#_*_coding:utf-8_*_

import info_collection
from conf import settings
import urllib,urllib2,sys,os,json,datetime
import api_token


class ArgvHandler(object):
    def __init__(self,argv_list):
        self.argvs = argv_list
        self.parse_argv()


    def parse_argv(self):
        if len(self.argvs) >1:
            if hasattr(self,self.argvs[1]):
                func = getattr(self,self.argvs[1])
                func()
            else:
                self.help_msg()
        else:
            self.help_msg()
#帮助菜单.有参数就执行,没参数打印帮助
    def help_msg(self):
        msg = '''
        collect_data        收集硬件信息
        run_forever			永远运行
        get_asset_id		获取资产ID
        report_asset        收集硬件信息并汇报 
        '''
        print(msg)

    def collect_data(self):
        """收集硬件信息"""
        obj = info_collection.InfoCollection()
        asset_data = obj.collect()
		#加上括号不是类就是方法这里显然是方法,因为我给它赋了一个obj
        #print asset_data
#

    def run_forever(self):
        pass

    def __attach_token(self,url_str):
        '''generate md5 by token_id and username,and attach it on the url request'''
        user = settings.Params['auth']['user']
        token_id = settings.Params['auth']['token']

        md5_token,timestamp = api_token.get_token(user,token_id)
        url_arg_str = "user=%s&timestamp=%s&token=%s" %(user,timestamp,md5_token)
        if "?" in url_str:#already has arg
            new_url = url_str + "&" + url_arg_str
        else:
            new_url = url_str + "?" + url_arg_str
        return  new_url
        #print(url_arg_str)

    def __submit_data(self,action_type,data,method):
	
		'''
		send data to server
		param action_type:url
		param data:具体要发送的数据
		param method :get/post
		return:
		'''

        if action_type in settings.Params['urls']:
            if type(settings.Params['port']) is int:
                url = "http://%s:%s%s" %(settings.Params['server'],settings.Params['port'],settings.Params['urls'][action_type]) #有端口
            else:
                url = "http://%s%s" %(settings.Params['server'],settings.Params['urls'][action_type]) #没有端口

            url =  self.__attach_token(url)  #端口验证
            print('Connecting [%s], it may take a minute' % url)
            if method == "get":
                args = ""
                for k,v in data.items():
                    args += "&%s=%s" %(k,v)
                args = args[1:]
                url_with_args = "%s?%s" %(url,args)
                try:
                    req = urllib2.Request(url_with_args)
                    req_data = urllib2.urlopen(req,timeout=settings.Params['request_timeout'])
                    callback = req_data.read()
                    print("-->server response:",callback)
                    return callback
                except urllib2.URLError as e:
                    sys.exit("\033[31;1m%s\033[0m"%e)
            elif method == "post":
                try:
                    data_encode = urllib.urlencode(data)
                    req = urllib2.Request(url=url,data=data_encode)
                    res_data = urllib2.urlopen(req,timeout=settings.Params['request_timeout'])
                    callback = res_data.read()
                    callback = json.loads(callback)
                    print("\033[31;1m[%s]:[%s]\033[0m response:\n%s" %(method,url,callback))
                    return callback
                except Exception as e:
                    sys.exit("\033[31;1m%s\033[0m"%e)
        else:
            raise KeyError



    #def __get_asset_id_by_sn(self,sn):
    #    return  self.__submit_data("get_asset_id_by_sn",{"sn":sn},"get")
    def load_asset_id(self,sn=None):
        asset_id_file = settings.Params['asset_id']
        has_asset_id = False
        if os.path.isfile(asset_id_file):
            asset_id = open(asset_id_file).read().strip()
            if asset_id.isdigit():
                return  asset_id
            else:
                has_asset_id =  False
        else:
            has_asset_id =  False

    def __update_asset_id(self,new_asset_id):
        asset_id_file = settings.Params['asset_id']
        f = open(asset_id_file,"wb")
        f.write(str(new_asset_id))
        f.close()


    def report_asset(self):
        obj = info_collection.InfoCollection()
        asset_data = obj.collect()
		 """
		 asset_id是干什么的?
		 def log_record
		 """
        asset_id = self.load_asset_id(asset_data["sn"])
		"""
		为什么要oad_asset_id,拿到文件名
		第一次回报肯定没有,但是我不知道你是第几次,所以只能用这个资产id来判断
		"""
        if asset_id: #reported to server before
            asset_data["asset_id"] = asset_id
            post_url = "asset_report"
        else:#first time report to server
            '''report to another url,this will put the asset into approval waiting zone, when the asset is approved ,this request returns
            asset's ID'''

            asset_data["asset_id"] = None
            post_url = "asset_report_with_no_id"

		"""
		首先要判断文件存在不,如果存在就判断是不是一个整数,要取资产ID
		post_url是干什么的?
		为了不影响全局我单独写一个URL,name是什么,是一个变量l
		"""
        data = {"asset_data": json.dumps(asset_data)}
        response = self.__submit_data(post_url,data,method="post")
		
		
        if "asset_id" in response:
            self.__update_asset_id(response["asset_id"])

        self.log_record(response)
		
		 """
		 asset_id是干什么的?
		 def log_record
		 """

    def log_record(self,log,action_type=None):
        f = open(settings.Params["log_file"],"ab")
        if log is str:
            pass
        if type(log) is dict:

            if "info" in log:
                for msg in log["info"]:
                    log_format = "%s\tINFO\t%s\n" %(datetime.datetime.now().strftime("%Y-%m-%d-%H:%M:%S"),msg)
                    #print msg
                    f.write(log_format)
            if "error" in log:
                for msg in log["error"]:
                    log_format = "%s\tERROR\t%s\n" %(datetime.datetime.now().strftime("%Y-%m-%d-%H:%M:%S"),msg)
                    f.write(log_format)
            if "warning" in log:
                for msg in log["warning"]:
                    log_format = "%s\tWARNING\t%s\n" %(datetime.datetime.now().strftime("%Y-%m-%d-%H:%M:%S"),msg)
                    f.write(log_format)

        f.close()

urllib.request read()

Windows PowerShell
版权所有 (C) 2009 Microsoft Corporation。保留所有权利。

PS C:\Users\Administrator> python
Python 3.5.3 (v3.5.3:1880cb95a742, Jan 16 2017, 16:02:32) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import urllib.request
>>> urllib.request.urlopen("http://www.baidu.com")
<http.client.HTTPResponse object at 0x0000000002C38B00>
>>> rep =  urllib.request.urlopen("http://www.baidu.com")
>>> rep.read()
b'<!DOCTYPE html>\n<!--STATUS OK-->\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\
n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\
n\r\n\r\n\r\n\r\n\r\n\t\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\
r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\t\r\n        \r\n\t\t\t        \r\n\t\r\n\t\t\t        \r\n\t\r\n\t\t\t        \r\n\
t\r\n\t\t\t        \r\n\t\t\t    \r\n\r\n\t\r\n        \r\n\t\t\t        \r\n\t\r\n\t\t\t        \r\n\t\r\n\t\t\t
 \r\n\t\r\n\t\t\t        \r\n\t\t\t    \r\n\r\n\r\n\r\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\r\n\n<html>\n<head>\n    \
n    <meta http-equiv="content-type" content="text/html;charset=utf-8">\n    <meta http-equiv="X-UA-Compatible" content=
"IE=Edge">\n\t<meta content="always" name="referrer">\n    <meta name="theme-color" content="#2932e1">\n    <link rel="s
hortcut icon" href="/favicon.ico" type="image/x-icon" />\n    <link rel="search" type="application/opensearchdescription
+xml" href="/content-search.xml" title="\xe7\x99\xbe\xe5\xba\xa6\xe6\x90\x9c\xe7\xb4\xa2" />\n    <link rel="icon" sizes
="any" mask href="//www.baidu.com/img/baidu_85beaf5496f291521eb75ba38eacbd87.svg">\n\t\n\t\n\t<link rel="dns-prefetch" h
ref="//s1.bdstatic.com"/>\n\t<link rel="dns-prefetch" href="//t1.baidu.com"/>\n\t<link rel="dns-prefetch" href="//t2.bai
du.com"/>\n\t<link rel="dns-prefetch" href="//t3.baidu.com"/>\n\t<link rel="dns-prefetch" href="//t10.baidu.com"/>\n\t<l
ink rel="dns-prefetch" href="//t11.baidu.com"/>\n\t<link rel="dns-prefetch" href="//t12.baidu.com"/>\n\t<link rel="dns-p
...省略
to_empty=!0,window.__switch_add_mask=!0;var s="http://s1.bdstatic.com/r/www/cache/static/global/js/all_async_search_eef4
222.js",n="/script";document.write("<script src=\'"+s+"\'><"+n+">"),bds.comm.newindex&&$(window).on("index_off",function
(){$(\'<div class="c-tips-container" id="c-tips-container"></div>\').insertAfter("#wrapper"),window.__sample_dynamic_tab
&&$("#s_tab").remove()\n}),bds.comm&&bds.comm.ishome&&Cookie.get("H_PS_PSSID")&&(bds.comm.indexSid=Cookie.get("H_PS_PSSI
D"))}();</script>\r\n\r\n\r\n\r\n<script>\r\nif(bds.comm.supportis){\r\n    window.__restart_confirm_timeout=true;\r\n
  window.__confirm_timeout=8000;\r\n    window.__disable_is_guide=true;\r\n    window.__disable_swap_to_empty=true;\r\n}
\r\ninitPreload({\r\n    \'isui\':true,\r\n    \'index_form\':"#form",\r\n    \'index_kw\':"#kw",\r\n    \'result_form\'
:"#form",\r\n    \'result_kw\':"#kw"\r\n});\r\n</script>\r\n\r\n<script>\r\nif(navigator.cookieEnabled){\r\n\tdocument.c
ookie="NOJS=;expires=Sat, 01 Jan 2000 00:00:00 GMT";\r\n}\r\n</script>\r\n\r\n\n\n</body>\n</html>\n\r\n\r\n\r\n\n\r\n'
>>>

url拼接截图

6、info_collection注释

#_*_coding:utf-8_*_

from plugins import plugin_api
import json,platform,sys


class InfoCollection(object):
	'''手机信息'''
    def __init__(self):
        pass

    def get_platform(self):

        os_platform = platform.system()
		'''
		获取平台是linux还是window
		>>> import platform
		>>> platform.system()
		'Windows'
		>>>
		
		[root@adminset ~]# python
		Python 2.7.5 (default, Apr 11 2018, 07:36:10)
		[GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] on linux2
		Type "help", "copyright", "credits" or "license" for more information.
		>>> import platform
		>>> platform.system()
		'Linux'
		>>>
		'''

        return os_platform

    def collect(self):
        os_platform = self.get_platform()
		'''
		通过类反射看有没有相应的平台
		'''
        try:
            func = getattr(self,os_platform)
            info_data = func()
			'''
		    获取的数据返回给collect平台了
			'''
            formatted_data = self.build_report_data(info_data)
            return formatted_data
        except AttributeError as e:
            sys.exit("Error:MadKing doens't support os [%s]! " % os_platform)

    def Linux(self):
        sys_info = plugin_api.LinuxSysInfo()

        return sys_info

    def Windows(self):
        sys_info = plugin_api.WindowsSysInfo()
        print(sys_info)
        #f = file('data_tmp.txt','wb')
        #f.write(json.dumps(sys_info))
        #f.close()
        return sys_info

    def build_report_data(self,data):

        #add token info in here before send

        return data

7、api_token注释

#_*_coding:utf-8_*_

import hashlib,time

def get_token(username,token_id):
    timestamp = int(time.time())
    md5_format_str = "%s\n%s\n%s" %(username,timestamp,token_id)
    obj = hashlib.md5()
    obj.update(md5_format_str)
    print "token format:[%s]" % md5_format_str
    print "token :[%s]" % obj.hexdigest()
    return obj.hexdigest()[10:17], timestamp


if __name__ =='__main__':
    print get_token('alex','test')

8、settings注释

#_*_coding:utf8_*_

import os
BaseDir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

Params = {
    "server": "192.168.1.38",
    "port":9000,
    'request_timeout':30,
    "urls":{
          "asset_report_with_no_id":"/asset/report/asset_with_no_asset_id/", #新资产批准区
          "asset_report":"/asset/report/",#正式资产表
        },
    'asset_id': '%s/var/.asset_id' % BaseDir,
	'''
	你从服务器拿到资产ID,你只能存到文件里,你不肯呢个在本地建一个数据库吧!
	存到var下,为什么是一个隐藏文件?
	liunx的所有的进程号存在文件里,而且是隐藏的,所以我也存文件
	'''
    'log_file': '%s/logs/run_log' % BaseDir,

    'auth':{
        'user':'lijie3721@126.com',
        'token': 'abc'
        },
}

9、plugin_api注释

#_*_coding:utf-8_*_

from linux import sysinfo

def LinuxSysInfo():
    #print __file__
    return  sysinfo.collect()


def WindowsSysInfo():
    from windows import sysinfo as win_sysinfo
    return win_sysinfo.collect()
	
'''
window的导入模块为什么写在下面,,这个是需要单独安装,
因为写在文件头,安装Linux的时候没有这个包会报错
'''

10、sysinfo注释

#_*_coding:utf-8_*_
__author__ = 'Alex Li'


import platform
import win32com
import wmi
import os


def collect():
    data = {
        'os_type': platform.system(),
        'os_release':"%s %s  %s "%( platform.release() ,platform.architecture()[0],platform.version()),
        'os_distribution': 'Microsoft',
        'asset_type':'server'
    }
    #data.update(cpuinfo())
    win32obj = Win32Info()
    data.update(win32obj.get_cpu_info())
    data.update(win32obj.get_ram_info())
    data.update(win32obj.get_server_info())
    data.update(win32obj.get_disk_info())
    data.update(win32obj.get_nic_info())

    #for k,v in data.items():
    #    print k,v
    return data
class Win32Info(object):
    def __init__(self):
        self.wmi_obj = wmi.WMI()
        self.wmi_service_obj = win32com.client.Dispatch("WbemScripting.SWbemLocator")
        self.wmi_service_connector =self.wmi_service_obj.ConnectServer(".","root\cimv2")

    def get_cpu_info(self):
        data = {}
        cpu_lists = self.wmi_obj.Win32_Processor()
        cpu_core_count = 0

        for cpu in cpu_lists:
            cpu_core_count += cpu.NumberOfCores
            cpu_model = cpu.Name
        data["cpu_count"] = len(cpu_lists)
        data["cpu_model"] = cpu_model
        data["cpu_core_count"] =cpu_core_count
        return data

    def get_ram_info(self):
        data = []
        ram_collections = self.wmi_service_connector.ExecQuery("Select * from Win32_PhysicalMemory")
        for item in ram_collections:
            item_data = {}
            #print item
            mb = int(1024 * 1024)
            ram_size = int(item.Capacity) / mb
            item_data = {
                "slot":item.DeviceLocator.strip(),
                "capacity":ram_size,
                "model":item.Caption,
                "manufactory":item.Manufacturer,
                "sn":item.SerialNumber,
            }
            data.append(item_data)
        #for i in data:
        #    print i
        return {"ram":data}
    def get_server_info(self):
        computer_info =  self.wmi_obj.Win32_ComputerSystem()[0]
        system_info =  self.wmi_obj.Win32_OperatingSystem()[0]
        data = {}
        data['manufactory'] = computer_info.Manufacturer
        data['model'] = computer_info.Model
        data['wake_up_type'] = computer_info.WakeUpType
        data['sn'] = system_info.SerialNumber
        #print data
        return data

    def get_disk_info(self):
        data = []
        for disk in self.wmi_obj.Win32_DiskDrive():
            #print  disk.Model,disk.Size,disk.DeviceID,disk.Name,disk.Index,disk.SerialNumber,disk.SystemName,disk.Description
            item_data = {}
            iface_choices = ["SAS","SCSI","SATA","SSD"]
            for iface in iface_choices:
                if iface in disk.Model:
                    item_data['iface_type']  = iface
                    break
            else:
                item_data['iface_type']  = 'unknown'
            item_data['slot']  = disk.Index
            item_data['sn']  = disk.SerialNumber
            item_data['model']  = disk.Model
            item_data['manufactory']  = disk.Manufacturer
            item_data['capacity']  = int(disk.Size ) / (1024*1024*1024)
            data.append(item_data)
        return {'physical_disk_driver':data}
    def get_nic_info(self):
        data = []
        for nic in self.wmi_obj.Win32_NetworkAdapterConfiguration():
            if nic.MACAddress is not None:
                item_data = {}
                item_data['macaddress'] = nic.MACAddress
                item_data['model'] = nic.Caption
                item_data['name'] = nic.Index
                if nic.IPAddress  is not None:
                    item_data['ipaddress'] = nic.IPAddress[0]
                    item_data['netmask'] = nic.IPSubnet
                else:
                    item_data['ipaddress'] = ''
                    item_data['netmask'] = ''
                bonding = 0
                #print nic.MACAddress ,nic.IPAddress,nic.ServiceName,nic.Caption,nic.IPSubnet
                #print item_data
                data.append(item_data)
        return {'nic':data}
if __name__=="__main__":
    collect()

获取cpu信息

PS Y:\MadkingClient> python
Python 3.5.3 (v3.5.3:1880cb95a742, Jan 16 2017, 16:02:32) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import platform
>>> import win32com
>>> import wmi
>>> import os
>>> wmi_obj = wmi.WMI()
>>> wmi_service_obj = win32com.client.Dispatch("WbemScripting.SWbemLocator")
>>> wmi_service_connector = wmi_service_obj.ConnectServer(".","root\cimv2")
>>> wmi_obj.Win32_Processor()
[<_wmi_object: b'\\\\XK104\\root\\cimv2:Win32_Processor.DeviceID="CPU0"'>]
>>> cpu_list = wmi_obj.Win32_Processor()
>>> dir(cpu_list[0])
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattr__', '__getat
tribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__re
duce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_associated_classes'
, '_cached_associated_classes', '_cached_methods', '_cached_properties', '_getAttributeNames', '_get_keys', '_instance_o
f', '_keys', '_methods', '_properties', 'associated_classes', 'associators', 'derivation', 'id', 'keys', 'methods', 'ole
_object', 'path', 'properties', 'property_map', 'put', 'qualifiers', 'references', 'set', 'wmi_property']
>>> cpu = cpu_list[0]
>>> cpu.id
'winmgmts:{authenticationlevel=pktprivacy,impersonationlevel=impersonate}!\\\\xk104\\root\\cimv2:win32_processor.devicei
d="cpu0"'
>>> cpu.Name
'Intel(R) Core(TM) i5-4570 CPU @ 3.20GHz'
>>> cpu.NumberOfCores
4

获取内存信息

PS C:\Users\Administrator> python
Python 3.5.3 (v3.5.3:1880cb95a742, Jan 16 2017, 16:02:32) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import platform
>>> import win32com
>>> import wmi
>>> import os
>>> wmi_service_obj = win32com.client.Dispatch("WbemScripting.SWbemLocator")
>>> wmi_service_connector = wmi_service_obj.ConnectServer(".","root\cimv2")
>>> ram_collections = wmi_service_connector.ExecQuery("Select * from Win32_PhysicalMemory")
>>> ram_collections
<COMObject <unknown>>
>>> for i in ram_collections:
... print(i.Capacity,i.Caption,i.Manufacturer,i.SerialNumber,i.DeviceLocator)
...
8589934592 Physical Memory Kingston 16474864 ChannelB-DIMM1
>>> 

遇到的坑:

1、Python中expected an indented block 缩进的问题

2、Manufacturer单词写错

收集资产截图

11、新资产待审批区表结构注释

class NewAssetApprovalZone(models.Model):
    """新资产待审批区"""

    sn = models.CharField(u'资产SN号', max_length=128, unique=True)
    asset_type_choices = (
        ('server', u'服务器'),
        ('switch', u'交换机'),
        ('router', u'路由器'),
        ('firewall', u'防火墙'),
        ('storage', u'存储设备'),
        ('NLB', u'NetScaler'),
        ('wireless', u'无线AP'),
        ('software', u'软件资产'),
        ('others', u'其它类'),
    )
    asset_type = models.CharField(choices=asset_type_choices, max_length=64, blank=True, null=True)
    manufactory = models.CharField(max_length=64, blank=True, null=True)
    model = models.CharField(max_length=128, blank=True, null=True)
    ram_size = models.IntegerField(blank=True, null=True)
    cpu_model = models.CharField(max_length=128, blank=True, null=True)
    cpu_count = models.IntegerField(blank=True, null=True)
    cpu_core_count = models.IntegerField(blank=True, null=True)
    os_distribution = models.CharField(max_length=64, blank=True, null=True)
    os_type = models.CharField(max_length=64, blank=True, null=True)
    os_release = models.CharField(max_length=64, blank=True, null=True)
	
	"""
	客户端过来的数据会临时存到临时表里
	上面的字段都不重要,重要的就是下面的data,data里面会存上面?存所有的资产信息
	"""
	
    data = models.TextField(u'资产数据')
    date = models.DateTimeField(u'汇报日期', auto_now_add=True)
    approved = models.BooleanField(u'已批准', default=False)
    approved_by = models.ForeignKey('UserProfile', verbose_name=u'批准人', blank=True, null=True)
    approved_date = models.DateTimeField(u'批准日期', blank=True, null=True)

    def __str__(self):
        return self.sn

    class Meta:
        verbose_name = '新上线待批准资产'
        verbose_name_plural = "新上线待批准资产"

  

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!