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 = "新上线待批准资产"

  

CMDB资产管理系统开发【day25】:windows客户端开发的更多相关文章

  1. Python之CMDB资产管理系统

    最近正好在给公司做CMDB资产管理系统,现在做的也差不多了,现在回头吧思路整理下. CMDB介绍 CMDB --Configuration Management Database 配置管理数据库, C ...

  2. CMDB资产管理系统开发【day25】:表结构设计1

    资产表 # _*_coding:utf-8_*_ __author__ = 'jieli' from assets.myauth import UserProfile from django.db i ...

  3. CMDB资产管理系统开发【day26】:CMDB上节回顾

    一.上节知识点回顾 服务器设计了一个表结构 开发了一个客户端 二.后台创建缓存区表 客户端连接服务器,在服务器的下面看报错信息 因为URL都没有写,所以我找不到呀 1.在MadKing\url.py ...

  4. C#.NET 大型通用信息化系统集成快速开发平台 4.0 版本 - 多系统开发接口 - 苹果客户端开发接口

    最近工作上需要,给苹果客户端开发接口,实现集中统一的用户管理,下面是接口调用参考. 1: 获取OpenId? http://127.0.0.1/GetOpenId.ashx?username=Admi ...

  5. CMDB资产管理系统开发【day25】:需求分析

    本节内容 浅谈ITIL CMDB介绍 Django自定义用户认证 Restful 规范 资产管理功能开发 浅谈ITIL TIL即IT基础架构库(Information Technology Infra ...

  6. CMDB资产管理系统开发【day25】:表结构设计2

    表结构设计1详细注释代码 # _*_coding:utf-8_*_ __author__ = 'luoahong' from assets.myauth import UserProfile from ...

  7. CMDB资产管理系统开发【day26】:linux客户端开发

    客户端疑难点及获取流程 1.linux客户端支持2就可以,python3就是很麻烦 难道你要求所有的客户端都上pytho3吗? 现在从bin的入口进去 HouseStark.ArgvHandler(s ...

  8. CMDB资产管理系统开发【day25】:Django 自定义用户认证

    官方文档:https://docs.djangoproject.com/en/1.10/topics/auth/customizing/#substituting-a-custom-user-mode ...

  9. CMDB资产管理系统开发【day26】:数据正式存入待存区

    1.from表单提交 1.数据提交到哪里呢? 提交到assets/new_assets_approval.html这了 2.Yes, I'm sure提交了什么?          为什么没有下拉框了 ...

随机推荐

  1. CSS优先级的及其衡量标准CSS权重

    一.背景 CSS有三大特性:层叠性.继承性.优先级. 而我们在给CSS定义样式的时候,经常出现两个及以上的规则应用在同一元素上,单该元素最终在浏览器呈现的效果是应用的哪个规则呢?这就要考虑优先级的问题 ...

  2. 【原】Java学习笔记016 - 面向对象

    package cn.temptation; public class Sample01 { public static void main(String[] args) { // this 关键字 ...

  3. oracle EM 如何调整界面显示的语言

    EM是通过浏览器语言来识别界面语言的,没有选项调整.我以chrome为例将默认中文改为英文: EM调整前为中文界面: 调整chrome语言显示为英文: 再重新开一个窗口,打开EM,界面已经调整为英文了 ...

  4. Docker的使用初探(二):Docker与.NET Core的结合

    目录 Docker的使用初探(二):Docker与.NET Core的结合 添加Dockefile 1. 在创建项目时添加 2. 手动添加 3. 容器业务流程协调控制程序支持 Dockefile语法 ...

  5. Java使用volatile实现多线程输出ABC共10次

    问题 有A,B,C三个线程, A线程输出A, B线程输出B, C线程输出C.要求,同时启动三个线程, 按顺序输出ABC, 循环10次. 今天在写多线程的时候找例子,见到了这样一个题,觉得不难,但是在网 ...

  6. 云数据库PolarDB(一)

    一.出现的背景及PolarDB简介 阿里云,中国第一家拥有完整云计算能力的企业. 2015年,在计算界的奥运会Sort Benchmark中,阿里云计算100TB数据排序只用了不到7分钟,把Apach ...

  7. linux服务器硬盘IO读写负载高来源定位 pt-ioprofile

    首先 .用top命令查看   1 2 3 4 5 top - 16:15:05 up 6 days,  6:25,  2 users,  load average: 1.45, 1.77, 2.14 ...

  8. python之并发编程

    一 背景知识 顾名思义,进程即正在执行的一个过程.进程是对正在运行程序的一个抽象. 进程的概念起源于操作系统,是操作系统最核心的概念,也是操作系统提供的最古老也是最重要的抽象概念之一.操作系统的其他所 ...

  9. CSAPP:第八章 异常控制流2

    CSAPP:第八章 异常控制流2 关键点:进程控制.信号 8.4 进程控制8.5 信号 8.4 进程控制   Unix提供了大量从C程序中操作进程的系统调用.8.4.1 获取进程ID  每个进程都有一 ...

  10. react的jsx语法

    在webpack.config.js中配置解析的loader { test:/\.jsx?$/, use:{ loader:"babel-loader", options:{ pr ...