def m2m_changed(sender, instance, action, reverse, model, pk_set, using, **kwargs):
    """https://docs.djangoproject.com/es/1.10/ref/signals/#m2m-changed"""
    try:
        with transaction.atomic():
            if not should_audit(instance):
                return False

            if action not in ("post_add", "post_remove", "post_clear"):
                return False

            object_json_repr = serializers.serialize("json", [instance])

            if reverse:
                event_type = CRUDEvent.M2M_CHANGE_REV
                # add reverse M2M changes to event. must use json lib because
                # django serializers ignore extra fields.
                tmp_repr = json.loads(object_json_repr)

                m2m_rev_field = _m2m_rev_field_name(instance._meta.concrete_model, model)
                related_instances = getattr(instance, m2m_rev_field).all()
                related_ids = [r.pk for r in related_instances]

                tmp_repr[0]['m2m_rev_model'] = force_text(model._meta)
                tmp_repr[0]['m2m_rev_pks'] = related_ids
                tmp_repr[0]['m2m_rev_action'] = action
                object_json_repr = json.dumps(tmp_repr)
            else:
                event_type = CRUDEvent.M2M_CHANGE

            # user
            try:
                user = get_current_user()
                # validate that the user still exists
                user = get_user_model().objects.get(pk=user.pk)
            except:
                user = None

            if isinstance(user, AnonymousUser):
                user = None
            c_t = ContentType.objects.get_for_model(instance)
            sid = transaction.savepoint()

            try:
                with transaction.atomic():
                    crud_event = CRUDEvent.objects.create(
                        event_type=event_type,
                        object_repr=str(instance),
                        object_json_repr=object_json_repr,
                        content_type_id=c_t.id,
                        object_id=instance.pk,
                        user_id=getattr(user, 'id', None),
                        datetime=timezone.now(),
                        user_pk_as_string=str(user.pk) if user else user
                    )
            except Exception as e:
                logger.exception(
                    "easy audit had a pre-save exception on CRUDEvent creation. instance: {}, instance pk: {}".format(
                        instance, instance.pk))
                transaction.savepoint_rollback(sid)
    except Exception:
        logger.exception('easy audit had an m2m-changed exception.')