django-生成详细的操作日志

django-生成详细的操作日志

需求:

当用户登录系统,修改表单中的值后,要生成详细的操作日志:

1.联系人由”张三”变为”李四”,联系电话由”AAA”变为”BBB”
2.联系地址由”某区某街道”变为”D区B街道”,联系电话由”AAA”变为”BBB”

思路

1.像 联系人、联系电话、联系地址… 这些数据可以从django model的verbose_name属性获取(在您设置了此属性值的情况下)。
2.由”旧数据”变为”新数据”,需要做新旧数据的对比,即遍历旧的model实例对象与新的model实例对象中的各字段一一对比。

代码实现

1.建立model

在models.py 文件中创建以下两个model:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import unicode_literals
from django.db import models


class Test(models.Model):
    """
    测试model
    """
    province = models.CharField(max_length=32, null=True, blank=True, verbose_name="省")
    city = models.CharField(max_length=32, null=True, blank=True, verbose_name="市")
    address = models.CharField(max_length=100, null=True, blank=True, verbose_name="详细地址")
    name = models.CharField(max_length=150, null=True, blank=True, verbose_name="名称")

    def __str__(self):
        return self.ktv_name


class OperationLogs(models.Model):
    """操作日志"""
    type = models.CharField(default="ktv", max_length=64, verbose_name="类型")  # 可根据model名称等...根据各自的需求做此字段的取舍
    content = models.TextField(verbose_name="修改详情", null=True)

2.编写日志生成函数

在views下创建operationlogs.py文件:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from myapp.models import OperationLogs
from datetime import datetime


def operationlogs(object_old_model, dict_update_fields, type, msg=None):
    """
    操作日志
    :param object_old_model: 旧的model对象实例
    :param dict_update_fields: 更新的字段键值对--字典格式
    :param type: 类型 (自己定义)
    :param msg: 自定义日志内容 (如果日志格式非‘A由aa变为bb’,可使用此参数)
    :return:
    """
    content = ''

    if object_old_model is not None and dict_update_fields is not None:
        fielddic = getmodelfield(object_old_model)
        for key, val in dict_update_fields.items():
            if isinstance(val, dict):  # 获取外键表的字段值
                _model = getattr(object_old_model, key)
                for _key, _val in val.items():  # key->外键名
                    if _key == "id":  # 主键id不参与对比
                        pass
                    else:
                        if not _model:  # 如果原值为null,做单独处理
                            _rtn = '"%s"由""变为"%s";' % (fielddic[key], _val)
                        else:  # 如果原值不为null,调用对比函数处理
                            _rtn = compare(getattr(_model, _key), _val, fielddic[key], msg)
                        content = content + _rtn
            else:
                _rtn = compare(getattr(object_old_model, key), val, fielddic[key], msg)
                content = content + _rtn
    else:
        content = msg

    #  存储日志
    if content == '':
        pass
    else:
        obj_operationlogs = OperationLogs()
        obj_operationlogs.content = content
        obj_operationlogs.type = type
        obj_operationlogs.save()


def getmodelfield(modelname):
    """获取model 指定字段的 verbose_name属性值"""
    fielddic={}
    for field in modelname._meta.fields:
        fielddic[field.name] = field.verbose_name
    return (fielddic)


def compare(oldstr, newstr, field, msg):
    """
    生成操作日志详细记录
    :param oldstr: 原值
    :param newstr: 新值
    :param field: 目标字段
    :return: content
    """
    content = ''

    if isinstance(newstr, list):  # 将list转为str类型,list对象存储到数据库后,为str类型
        newstr = str(newstr)

    if oldstr == newstr:  # 值未变化,不做处理
        pass
    else:
        if not msg:
            content = ('"%s"由"%s"变为"%s";' % (field, oldstr, newstr))
        else:
            content = ('%s"%s"由"%s"变为"%s";' % (msg, field, oldstr, newstr))
    return content

3.调用生成日志函数,产生日志

在需要生成日志的view方法中添加:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from myapp.models import Test
import copy 

def mypatch(request):
    ...
    datas = request.PATCH
    test = Test.objects.filter(id=datas["id"]).first()
    if test is not None:
        obj_old_test = copy.deepcopy(test)  # 生成操作日志使用
        update_fields = {"name": datas["name"]...}
        ...

        operationlogs(obj_old_test, update_fields, "testlogs")  # 操作日志
    ...

你可能感兴趣的:(django)