mirror of
https://github.com/jumpserver/jumpserver.git
synced 2026-07-02 07:01:30 +00:00
fix: enhance operator log handling and improve M2M field verbose name retrieval
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import json
|
||||
from datetime import datetime
|
||||
from uuid import UUID
|
||||
|
||||
from django.core.cache import cache
|
||||
from django.db import transaction
|
||||
@@ -42,13 +43,33 @@ class OperatorLogHandler(metaclass=Singleton):
|
||||
value2 = as_current_tz(value2).strftime('%Y-%m-%d %H:%M:%S')
|
||||
return value1, value2
|
||||
|
||||
@classmethod
|
||||
def _normalize_diff_value(cls, value):
|
||||
if isinstance(value, datetime):
|
||||
return as_current_tz(value).strftime('%Y-%m-%d %H:%M:%S')
|
||||
if isinstance(value, UUID):
|
||||
return str(value)
|
||||
if isinstance(value, dict):
|
||||
return {k: cls._normalize_diff_value(v) for k, v in value.items()}
|
||||
if isinstance(value, (list, tuple, set)):
|
||||
return [cls._normalize_diff_value(v) for v in value]
|
||||
return value
|
||||
|
||||
@classmethod
|
||||
def _value_equal_for_diff(cls, left, right):
|
||||
left = cls._normalize_diff_value(left)
|
||||
right = cls._normalize_diff_value(right)
|
||||
if left == right:
|
||||
return True
|
||||
|
||||
return str(left) == str(right)
|
||||
|
||||
def _look_for_two_dict_change(self, left_dict, right_dict):
|
||||
# 以右边的字典为基础
|
||||
before, after = {}, {}
|
||||
for key, value in right_dict.items():
|
||||
pre_value = left_dict.get(key, '')
|
||||
pre_value, value = self._consistent_type_to_str(pre_value, value)
|
||||
if sorted(str(value)) == sorted(str(pre_value)):
|
||||
if self._value_equal_for_diff(pre_value, value):
|
||||
continue
|
||||
before[key] = pre_value
|
||||
after[key] = value
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
import uuid
|
||||
from itertools import chain
|
||||
|
||||
from django.apps import apps
|
||||
from django.db.models.signals import (
|
||||
@@ -26,6 +27,28 @@ M2M_ACTION = {
|
||||
}
|
||||
|
||||
|
||||
def _get_m2m_field_verbose_name(instance, model, sender):
|
||||
opts = instance._meta
|
||||
for f in chain(opts.many_to_many, opts.related_objects):
|
||||
related_model = getattr(f, 'related_model', None)
|
||||
if related_model != model:
|
||||
continue
|
||||
|
||||
through = None
|
||||
remote_field = getattr(f, 'remote_field', None)
|
||||
if remote_field is not None:
|
||||
through = getattr(remote_field, 'through', None)
|
||||
if through is None:
|
||||
through = getattr(f, 'through', None)
|
||||
|
||||
if through is not sender:
|
||||
continue
|
||||
|
||||
verbose_name = getattr(f, 'verbose_name', None) or model._meta.verbose_name
|
||||
return str(verbose_name)
|
||||
return str(model._meta.verbose_name)
|
||||
|
||||
|
||||
@receiver(m2m_changed)
|
||||
def on_m2m_changed(sender, action, instance, reverse, model, pk_set, **kwargs):
|
||||
if action not in M2M_ACTION:
|
||||
@@ -39,15 +62,21 @@ def on_m2m_changed(sender, action, instance, reverse, model, pk_set, **kwargs):
|
||||
instance, include_model_fields=False, include_related_fields=[model]
|
||||
)
|
||||
|
||||
instance_id = current_instance.get('id')
|
||||
instance_id_data = current_instance.get('id', {})
|
||||
if isinstance(instance_id_data, dict):
|
||||
instance_id = instance_id_data.get('value')
|
||||
else:
|
||||
instance_id = instance_id_data
|
||||
log_id, before_instance = get_instance_dict_from_cache(instance_id)
|
||||
|
||||
field_name = str(model._meta.verbose_name)
|
||||
field_name = _get_m2m_field_verbose_name(instance, model, sender)
|
||||
pk_set = pk_set or {}
|
||||
objs = model.objects.filter(pk__in=pk_set)
|
||||
objs_display = [str(o) for o in objs]
|
||||
action = M2M_ACTION[action]
|
||||
changed_field = current_instance.get(field_name, {})
|
||||
if not changed_field and field_name != str(model._meta.verbose_name):
|
||||
changed_field = current_instance.get(str(model._meta.verbose_name), {})
|
||||
changed_value = changed_field.get('value', [])
|
||||
|
||||
after, before, before_value = None, None, None
|
||||
@@ -63,7 +92,7 @@ def on_m2m_changed(sender, action, instance, reverse, model, pk_set, **kwargs):
|
||||
before_change_field['value'] = before_value
|
||||
before = {field_name: before_change_field}
|
||||
|
||||
if sorted(str(before)) == sorted(str(after)):
|
||||
if before == after:
|
||||
return
|
||||
|
||||
create_or_update_operate_log(
|
||||
|
||||
Reference in New Issue
Block a user