当用户登录系统,修改表单中的值后,要生成详细的操作日志:
1.联系人由”张三”变为”李四”,联系电话由”AAA”变为”BBB”
2.联系地址由”某区某街道”变为”D区B街道”,联系电话由”AAA”变为”BBB”
1.像 联系人、联系电话、联系地址… 这些数据可以从django model的verbose_name属性获取(在您设置了此属性值的情况下)。
2.由”旧数据”变为”新数据”,需要做新旧数据的对比,即遍历旧的model实例对象与新的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)
在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
在需要生成日志的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") # 操作日志
...