• 学会这个Python技能,就可以跟excel说再见了


    资产登记,可能你想很简单,自己维护一份excel表不就行了吗?

    但它和设备的采购、维护和管理息息相关。

    领导可能随时问你“小宋,还剩多少内存条可以用啊?要不要申请维修a啊?”你一脸懵逼,反怼领导一句:这和我有什么关系?

    好像是没什么关系,所以我坚持用excel登记了几千条IT资产信息,每次打开慢的一匹。不信的话,看看我的劳动成果:

    图片

    累计电脑设备超过1000条,类型8种

    图片

    型号如戴尔台式主机OptiPlex的3020,7040,7060,9020系类,品牌包括戴尔、三星、苹果、宏基等等。

    这些有逻辑关系的数据,通过excel简单去添加,显然还是没有逻辑,说好的excel高效办公呢?我仔细看了会表格,又发现很多重复的内容,比如明明是相同型号,配置一样的,登记了几遍:

    图片

    这不是优秀的桌面维护人员该有的表格,咱不是文员,花9块9去学那种“七天学会excel”、“文员办公必学五大函数”的课程价值不大。简单一点,该删则删,该改则改,所以我整理了一遍表格,设计字段,用django去管理这些信息:

    完整代码在这里 https://gitee.com/sswfit/asset.git

    图片

    不吹不黑,立马轻松了很多:

    • 编辑模式批量修改

    图片

    • “+”“-”按钮动态增删搜索条件

    图片

    • 添加3个按钮“添加资产”、“添加型号”、“添加领用人”

    这样简单直接,刷刷刷几下,登记资产就很轻松了。

    有哪些值得注意的地方呢?

    表格的整理

    1. 每条资产一行数据。

    比如我领用了2个显示器,那就是2条资产,2行数据,而不是在excel中合并内容。

    1. 去掉配置等多余的列

    因为相同型号的配置是一样的,它可以在数据库中作为型号外键

    经过整理,1068条减少到340条,瘦身成功:

    图片

    1. xlrd模块将数据存入数据库

    xlrd的2.0.1版本,只支持.xls文件,读取.xlsx会报错。所以安装旧版xlrd:

    pip uninstall xlrd
    pip install xlrd==1.2.0
    
    • 1
    • 2

    将整理后的info.xlsx写入django数据库:

    import xlrd
    from datetime import datetime
    from api import models
    
    data = xlrd.open_workbook('d:/asset/api/info.xlsx')
    table = data.sheet_by_name('Sheet1')
    style_list = []
    for i in range(table.nrows):
        if type(table.row_values(i)[0]) is float and type(table.row_values(i)[1]) is float:
            # x为表里的“购置时间”
            x = xlrd.xldate_as_datetime(table.row_values(i)[0],0)
            # y为表里的“领用时间”
            y = xlrd.xldate_as_datetime(table.row_values(i)[1],0)
            data_list = table.row_values(i)
            #把表里的'2015年12月11日'格式转换为'2015-12-11'
            data_list[0] = x.strftime('%Y-%m-%d')
            data_list[1] = y.strftime('%Y-%m-%d')
            #django的Employee表
            employee_id = models.Employee.objects.filter(name=data_list[2]).first().id
            data_list[2] = employee_id
            style_id = models.Style.objects.filter(name=data_list[4]).first().id
            data_list[4] = style_id
            style_list.append(data_list[4])
        else:
            print('xx')
    print(data_list)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    data_list结果如下:

    ['2019-08-05', '2019-08-19', '空闲', 'SZMN1908006', '戴尔 E2417H', 880.0, '']
    
    • 1

    输出的值就是表格里的最后一行

    图片

    字段设计

    根据整理好的excel设计表结构,分为型号表、资产类型表、部门表、员工表、配置表、资产表。重点是Models型号表,它外键关联到Type资产类型表,一对一关联Configuration配置表

    models.py

    #型号表
    class Models(models.Model):
        name = models.CharField(max_length=32)
        type = models.ForeignKey('Type',to_field='id',related_name='type_name',on_delete=models.CASCADE,verbose_name='类别')
        configure = models.OneToOneField(to='Configuration',on_delete=models.CASCADE,verbose_name='配置',null=True,blank=True)
    
    #资产类型表,如手机、显示器等不同的资产类型
    class Type(models.Model):
        name = models.CharField(max_length=32,verbose_name='类别')
    
    #部门表
    class Department(models.Model):
        name = models.CharField(max_length=32)
    
    #员工表
    class Employee(models.Model):
        name = models.CharField(max_length=32,verbose_name='员工姓名')
        dept = models.ForeignKey('Department',on_delete=models.CASCADE,verbose_name='部门')
    
    #资产的配置(内存、cpu等)
    class Configuration(models.Model):
        cpu = models.CharField(max_length=32,blank=True,null=True)
        mem = models.CharField(max_length=32,blank=True,null=True,verbose_name='内存')
        harddisk = models.CharField(max_length=32,blank=True,null=True,verbose_name='硬盘')
        gpu = models.CharField(max_length=32,blank=True,null=True,verbose_name='显卡')
        screen = models.CharField(max_length=32,blank=True,null=True,verbose_name='显示器',default='N')
        note = models.CharField(max_length=32,blank=True,null=True,verbose_name='备注')
    
        def __str__(self):
            return 'CPU:%s 内存:%s 硬盘:%s 显卡:%s 显示器:%s 备注:%s' % (self.cpu,self.mem,self.harddisk,self.gpu,self.screen,self.note)
    
    #资产表
    class Asset(models.Model):
        supplier_type_choices = (
            (1, 'N'),
            (2,'戴尔'),
            (3, '苹果'),
        )
        status_choices = (
            (1,'空闲'),
            (2, '使用'),
            (3, '报废'),
            (4,'待确认')
        )
        mod = models.ForeignKey('Models',on_delete=models.CASCADE,verbose_name='型号')
        purchase_at = models.DateField(verbose_name='购买时间')
        price = models.CharField(max_length=32, verbose_name='价格',blank=True,null=True)
        recipient = models.ForeignKey('Employee',on_delete=models.CASCADE,verbose_name='领用人')
        recipient_at =  models.DateField(null=True,blank=True,verbose_name='领用时间')
        sn = models.CharField(max_length=32,verbose_name='资产编号')
        supplier = models.IntegerField(choices=supplier_type_choices,default=3,verbose_name='供应商')
        after_sales = models.CharField(max_length=128,blank=True,null=True,verbose_name='售后联系方式')
        status = models.IntegerField(choices=status_choices,default=1,verbose_name='状态')
        note = models.CharField(max_length=64,blank=True,null=True,verbose_name='备注',default='')
    
        def __str__(self):
            return self.sn
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    Type表,表示资产类型,如手机、显示器:

    图片

    Configuration表,表示资产的配置(内存、cpu等),可灵活添加:

    图片

    Models表,表示型号,如红米k20 pro,关联上面2个表:

    图片

    Asset表,表示每一条资产:

    图片

    领用人怎么排序的

    图片

    红框内的姓名按abcd顺序排序用到pypinyin模块,在另一篇“我用django偷偷绑定员工MAC信息”用它给员工分配过邮箱

    # recipient领用人
    recipient_list = list(models.Employee.objects.values('id','name'))
    recipient_list.sort(key=lambda x:lazy_pinyin(x['name']))
    
    
    • 1
    • 2
    • 3
    • 4

    逻辑处理

    逻辑还是比较简单的,后端先把需要的信息准备好,前端在页面初始化的时候拿到这些数据就可以做各种文章了。

    举个🌰,怎么让搜索条件在下拉框中显示呢?

    图片

    首先,定义一个url,它的作用就是把所有需要的数据提前准备好,一个json大字典

    url(r'asset-json',views.AssetJsonView.as_view(),name='asset-json'),
    
    
    • 1
    • 2

    对应的处理函数AssetJsonView:

    图片

    然后配置前端,一打开页面就获取这个json大字典

    图片

    可以直接访问 http://ssw.fit:8081/asset-json 看到这些数据:

    图片

    第二个红框里357 itmes就是数据库里的357条资产信息,全部在这个大字典里了。剩下的就是前端html怎么显示这些和javascript逻辑处理。

    当然,光提供数据还不够,AssetJsonView还处理批量修改,保存按钮就是提交给它的put()方法:

    图片

    put方法:

    图片

    主页面对应的url

    http://ssw.fit:8081/asset-0-0/, 它的url表示:

     url(r'^asset-(?P\d+)-(?P\d+)/$', views.handle_asset, name="asset")
    
    • 1

    作用主要是根据搜索条件过滤资产结果。

    对应的处理函数:

    def handle_asset(request,*args,**kwargs):
    
        username = request.session.get('username')
        #取出所有资产类型
        type_list = models.Type.objects.all()
        #资产当前的状态,空闲还是在使用
        status_list = models.Asset.status_choices
    
        #搜索条件放到一个字典里
        condition = {}
        r = reverse('asset',kwargs=kwargs)
        for k,v in kwargs.items():
            kwargs[k] = int(v)
            if v == '0':
                pass
            else:
                condition[k] = v
        arg_dict = kwargs
    
        #分页
        current_page = request.GET.get('p',1)
        current_page = int(current_page)
        total_count = models.Asset.objects.all().count()
    
        #根据搜索条件过滤资产结果
        asset_list = models.Asset.objects.filter(**condition)[obj.db_start:obj.db_end]
        if request.method == 'GET':
            q = request.GET.get('q')
            if q:
                rep = models.Employee.objects.filter(name__icontains=q).first()
                if rep:
                    asset_list = rep.asset_set.filter(**condition)
                    return render(request, 'asset.html', {'username': username, 'assets': asset_list, 'type_list': type_list, \
                                                          'status_list': status_list, 'arg_dict': arg_dict,
                                                          'q':q})
                else:
                    print('无此用户')
        return render(request,'asset.html',{'username':username,'assets':asset_list,'type_list':type_list,\
                                            'status_list':status_list,'arg_dict':arg_dict})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    可以克隆下来,看下前后端具体处理过程

    git clone https://gitee.com/sswfit/asset.git
    
    #启动方法
    python manage.py runserver localhost:8080
    python manage.py makemigrations
    python manage.py migrate
    
    #安装xlrd
    pip install -r requirements.txt
    
    #访问
    http://localhost:8080/asset-0-0/
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    小结

    这个案例挺实用的,因为增删改查的场景很多。

    可以个人用,也可以帮同事朋友设计一个。

    跟在电脑上打开一个记事本一样,随手记录资产,随手修改。

    而且,可以作为IT信息管理体系的一部分,

    向领导报告,我为规范企业IT设备管理做出了实际行动。

  • 相关阅读:
    4.2 抽象类
    [数据结构]什么是树?什么是二叉树?
    Map和Set知识点
    LeetCode 周赛上分之旅 #47 前后缀分解结合单调栈的贡献问题
    力扣160 - 相交链表【双指针妙解】
    Codeforces Round #804 (Div. 2)
    重入锁ReentrantLock详解
    【CKA考试笔记】十四、helm
    【工作迄今为止用的频率最高的13条git命令】
    干货 | 电商人看了这篇,再也不怕不会做时间规划管理啦
  • 原文地址:https://blog.csdn.net/qq_34160248/article/details/127253205