CMDB资产管理系统开发【day26】:数据正式存入待存区
1、from表单提交
1、数据提交到哪里呢?
提交到assets/new_assets_approval.html这了
2、Yes, I'm sure提交了什么?
为什么没有下拉框了 ?是因为我隐藏了,获取的的是资产id号,但是显示的是sn号
代码如下:
{% extends 'base.html' %} {% block page-container %} <div class="eq-height"> <div class="col-sm-4 eq-box-sm"> <!--Panel with Header--> <!--===================================================--> <div class="panel"> <div class="panel-heading"> <h3 class="panel-title" style="color: red; ">确认要将下列资产存入数据库么?</h3> </div> <div class="panel-body"> <form method="post" action="{% url 'new_assets_approval' %}">{% csrf_token %} /往后台写数据 <table class="table table-hover"> <tr> <th>#</th> <th>SN</th> <th>资产类型</th> <th>厂商</th> <th>型号</th> <th>CPU型号</th> <th>CPU颗数</th> <th>CPU核数</th> <th>内存大小</th> <th>汇报日期</th> </tr> {% for new_asset in new_assets %} <tr data-set="{{ new_asset.id }}"> <td>{{ forloop.counter }}</td> <td>{{ new_asset.sn }}</td> <td>{{ new_asset.asset_type }}</td> <td>{{ new_asset.manufactory }}</td> <td>{{ new_asset.model }}</td> <td>{{ new_asset.cpu_model}}</td> <td>{{ new_asset.cpu_count}}</td> <td>{{ new_asset.cpu_core_count}}</td> <td>{{ new_asset.ram_size}}</td> <td>{{ new_asset.date }}</td> {% if new_asset.id in response_dic %} <td><a href="#asset_{{ new_asset.id }}">执行结果</a></td> {% endif %} </tr> {% endfor %} </table> <select name="approved_asset_list" class="hide" multiple> {% for new_asset in new_assets %} <option value="{{ new_asset.id }}" selected>{{ new_asset.sn }}</option> {% endfor %} </select> 已经上就是提交的数据,只需要id就可以,但是显示的sn <input type="submit" value="Yes, I'm sure" class="btn btn-danger"> </form> <div > {% for key,msg in response_dic.items %} <div> {% for asset in new_assets %} {% if asset.id == key %} <h4 id="asset_{{ asset.id }}"><a style="color:deepskyblue" href="/admin/assets/asset/?q={{ asset.sn }}" target="_blank">{{ asset.sn }} </a> | {{ asset.manufactory }} {{ asset.model }} | {{ asset.cpu_model }} </h4> {% endif %} {% endfor %} <p style="color: green"> {% for item in msg.info %} {{ item |safe}} <br/> {% endfor %} </p> <p style="color: red"> {% for item in msg.error %} {% if 'Warning' in item.keys.0 %} <span style="color:orange;">{{ item }}</span> {% else %} {{ item }} {% endif %} <br/> {% endfor %} </p> </div> <hr/> {% endfor %} </div> </div> </div> <!--===================================================--> <!--End Panel with Header--> <button id="scroll-top" class="btn"><i class="fa fa-chevron-up"></i></button> </div> </div> {% endblock %}
3、两个对象你能批量存吗??
从临时库里把过滤出来,根据id取对象,取出来后存到正式库,问题是现在有2个对象,这两个对象你能批量存吗?
答:不能,只能用for循环去存,具体代码如下
2、改request.POST或者request.GET里面的内容
1、request.POST.copy()这是什么意思?
1、默认他是什么格式?
默认数据类型它是个字典
如果我要修改它,我往里放个key行不行
2、不复制修改无法修改
后台代码
request.POST = [ 'testkey' ]= 'haha' print('polst',request.POST.copy())
报错截图:
immutable 是一个不可变的,是一个只读的字典,
3、复制再修改就可以修改
后台代码
def new_assets_approval(request): if request.method == 'POST': request.POST = request.POST.copy() request.POST = [ 'testkey' ]= 'haha' print('polst',request.POST.copy())
控制台截图:
总结:
以后你在写项目的时候,可能会遇到你需要改request.POST或者request.GET里面的内容,
你想改但是你改却改不了,你就可以copy()一下
3、为什么要加asset_data这个字段
函数代码:
def new_assets_approval(request): if request.method == 'POST': request.POST = request.POST.copy() approved_asset_list = request.POST.getlist('approved_asset_list') approved_asset_list = models.NewAssetApprovalZone.objects.filter(id__in=approved_asset_list) '''从临时库里把过滤出来,根据id取对象,取出来后存到正式库,问题是现在有2个对象,这两个对象你能批量存吗?''' response_dic = {} for obj in approved_asset_list: request.POST['asset_data'] = obj.data ''' 往request.POST加了一个'asset_data'的key 为什么要加这个东西,必须要往这里硬塞一个数据?因为这个代码里面已经写死了,就是从命令行里发过来的参数里取数据 有可以兼容浏览器,又可以命令行 通过命令行把这个东西存 当做一个参数 '''' ass_handler = core.Asset(request) if ass_handler.data_is_valid_without_id(): ass_handler.data_inject() obj.approved = True obj.save() '''确认如果是新资产,是的话就写入,这里一写入我就存进去了,存进去了就变成已批准''' response_dic[obj.id] = ass_handler.response return render(request, 'assets/new_assets_approval.html', {'new_assets': approved_asset_list, 'response_dic': response_dic}) else: ids = request.GET.get('ids') id_list = ids.split(',') new_assets = models.NewAssetApprovalZone.objects.filter(id__in=id_list) return render(request, 'assets/new_assets_approval.html', {'new_assets': new_assets})
为什么要加这个东西,必须要往这里硬塞一个数据?
- 之前就是从命令行里发过来的参数里取数据
- 现在从浏览器里取数据,又塞到,因为这个代码里已经写死了不许要有这样一个数据
- 浏览器刚才没有给我发数据,这是给我发了一个资产id,通过这个id把临时库里的资产取出来,有塞到这里
- 所以说硬塞一个asset_data,是为了它又可以兼容浏览器,又可以兼容命令行
4、反查在cmdb中的应用
1、我刚开始创建的时候默认是server,我想把server这个值取出来,
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)
我获取的不是a.asset_type而是a.server
2、这里['asset_type']有没有一个叫server这个值
3、server到底是什么?
1、后台创建有一个3333资产表,只填写name和sn字段,其他什么都不填写
2、客户端获取看server到底是什么?
1、其实server就是server表,因为server表关里联了asset
def __is_new_asset代码如下:
def __is_new_asset(self): ''' 如何判断是不是新资产? asset_obj是哪里来的呢?我刚才从资产表里创建了一个只有资产ID的 如果我当前内存里已经有这个字段了,我就认为有这个资产, ''' if not hasattr(self.asset_obj, self.clean_data['asset_type']): # new asset return True else: return False
你们学过反查没?
- server表关联了asset表,就可以通过server就可以通过server.asset.字段去查获取asset里面的东西
- 反过来asset可以查询server里面的东西,通过表名是小写,如果没有server
你把就它写死了!你这次关联的是server,下次可能关联的是network,可扩展性不好!
- 因为linux客户端汇报过来的是写死了因为它是server
- 如果我会网络设备,它就是network
5、什么是**data_set
函数代码解析:
def __create_server_info(self, ignore_errs=False): try: self.__verify_field(self.clean_data, 'model', str if not len(self.response['error']) or ignore_errs == True: # no processing when there's no error happend #如果没有错误数据或者是忽略,才开始把这些 data_set = { 'asset_id': self.asset_obj.id, 'raid_type': self.clean_data.get('raid_type'), # 'model':self.clean_data.get('model'), 'os_type': self.clean_data.get('os_type'), 'os_distribution': self.clean_data.get('os_distribution'), 'os_release': self.clean_data.get('os_release'), } obj = models.Server(**data_set) #先生成一个字典,然后创建,之前存了一个,model obj.asset.model = self.clean_data.get('model') obj.save() return obj except Exception as e: self.response_msg('error', 'ObjectCreationException', 'Object [server] %s' % str(e))
obj = models.Server(**data_set)中的**data_set是什么意?
服务器端代码
class SecurityDevice(models.Model): """安全设备""" asset = models.OneToOneField('Asset') sub_assset_type_choices = ( (0, '防火墙'), (1, '入侵检测设备'), (2, '互联网网关'), (4, '运维审计系统'), ) sub_asset_type = models.SmallIntegerField(choices=sub_assset_type_choices, verbose_name="服务器类型", default=0) def __str__(self): return "%s" %self.asset.id
以前的写法
class Asset(models.Model): asset_type_choices = ( ('server', u'服务器'), ('networkdevice', u'网络设备'), ('storagedevice', u'存储设备'), ('securitydevice', u'安全设备'), ('securitydevice', 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, default='server') name = models.CharField(max_length=64, unique=True) sn = models.CharField(u'资产SN号', max_length=128, unique=True) manufactory = models.ForeignKey('Manufactory', verbose_name=u'制造商', null=True, blank=True) # model = models.ForeignKey('ProductModel', verbose_name=u'型号') # model = models.CharField(u'型号',max_length=128,null=True, blank=True )
注意看最后注销掉的2行
客户端截图
后台截图
注释掉验证函数测试
验证函数代码解析
def __verify_field(self, data_set, field_key, data_type, required=True): field_val = data_set.get(field_key) ''' 做一个数据类型的验证,判断cpu里判断是不是int类型,确保clean_data里model必须要有并且是一个字符串, 如果有,我就把model对应的值,尝试转成字符串 判断cpu里判断是不是int类型,,我觉得那个字段需要我就加那个,如果加不了,程序就不往下走了 ''' if field_val: try: data_set[field_key] = data_type(field_val) except ValueError as e: self.response_msg('error', 'InvalidField', "The field [%s]'s data type is invalid, the correct data type should be [%s] " % ( field_key, data_type)) elif required == True: self.response_msg('error', 'LackOfField', "The field [%s] has no value provided in your reporting data [%s]" % ( field_key, data_set))
服务端截图
作者:罗阿红
出处:http://www.cnblogs.com/luoahong/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。