首页 > 解决方案 > 在 Django 1.11 中的帖子保存中获取多对多字段更改

问题描述

因此,我的post_save代码中有一个信号来保存模型更改的日志,但是在触发点时未应用多对多字段的post_save更改,因此 m2m 字段的更改不会保存在我的日志中。

我的代码(您几乎可以忽略方法内的代码):

def save_log(sender, instance, created, raw, update_fields, **kwargs):
    if (
        not hasattr(sender, '_meta') or
        sender._meta.label not in settings.MODELS_TO_BE_LOGGED
    ):
        return

    sensitive_fields = ['password', ]

    user = get_user()

    # This creates the log with a json describing the changes
    if created:
        # This method creates a log
        instance.save_addition(user, '')
    else:
        changed_field_labels = {}
        original_dict = instance.original_dict
        actual_dict = instance.to_dict(
            exclude=['created_at', 'updated_at', 'original_dict', 'id'],
        )

        change = False
        for key in set(list(actual_dict.keys()) + list(original_dict.keys())):
            if original_dict.get(key) != actual_dict.get(key):
                change = True
                if key == sensitive_fields:
                    changed_field_labels[key] = {'change': 'field updated'}
                else:
                    changed_field_labels[key] = {
                        'from': original_dict.get(key, '-'),
                        'to': actual_dict.get(key, '-'),
                    }

        if change:
            json_message = json.dumps(
                {'changed': {'fields': changed_field_labels}},
                cls=ModelEncoder
            )
            # This method creates a log
            instance.save_edition(user, json_message)

例如,考虑一个模型Event,它有一个多对多字段来EventCategory调用categories。例如,如果通过 UpdateView 对事件进行了更改(包括对 的更改categories),并且调用了该方法,如果我这样做event.categories.all()了,它将显示以前的类别,而不进行更改。

我可以使用m2m_changed信号来保存日志,但它会创建单独的日志,例如如果有人将类别从 [A, B, C] 更改为 [A, B, D],它将触发两次,一次用于删除C,其他用于删除D,导致大量日志。我可以根据用户和日志创建时间来做诸如组日志之类的事情(如果日志是在 1 秒内创建的,我可以合并它们或其他东西)。

我可以做些什么来使用post_save钩子获取方法内部的更改吗?

谢谢。

标签: pythondjangodjango-signals

解决方案


推荐阅读