models.py
class OperationLog(models.Model):
model_name = models.CharField(max_length=100)
operation = models.CharField(max_length=100)
object_id = models.PositiveIntegerField()
created_at = models.DateTimeField(auto_now_add=True)
account = models.CharField(max_length=100, default='anonymous')
def __str__(self):
return f"{self.model_name} - {self.operation} - ID: {self.object_id}"
from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver
@receiver(post_save)
def create_operation_log(sender, instance=None, created=False, **kwargs):
if sender == OperationLog:
# 避免记录操作日志时出现循环调用
return
if created:
operation = 'create'
else:
operation = 'update'
# 解决报错 AttributeError: 'Migration' object has no attribute 'account'
if 'makemigrations' not in sys.argv and 'migrate' not in sys.argv:
OperationLog.objects.create(
model_name=sender._meta.model_name,
operation=operation,
object_id=instance.id,
account=instance.account
)
@receiver(post_delete)
def delete_operation_log(sender, instance=None, **kwargs):
if sender == OperationLog:
# 避免记录操作日志时出现循环调用
return
# 解决报错 AttributeError: 'Migration' object has no attribute 'account'
if 'makemigrations' not in sys.argv and 'migrate' not in sys.argv:
OperationLog.objects.create(
model_name=sender._meta.model_name,
operation='delete',
object_id=instance.id,
account=instance.account
)
其他表的字段默认包含id,如果需要记录其他字段,比如account,即操作人,那么需要每个表都有account字段就可以,比如这种:
class ImageUpload(models.Model):
sid = models.CharField(max_length=64, default=uuid.uuid4().hex) # ID
image = models.ImageField(upload_to='xxx/', default='xxx/default.png') # 文件
account = models.CharField(max_length=50, default='admin') # 更新用户
update_time = models.DateTimeField(auto_now=True) # 更新时间