以下の内容はhttps://kamatimaru.hatenablog.com/entry/2025/06/23/003719より取得しました。


django-auditlogで特定のユーザー種別の場合にログを抑制する方法

概要

django-auditlogというjazzbandの管轄のDjangoのモデル操作の監査ログを作成してくれるライブラリがあります。

github.com

基本的な使い方は以下の記事でryu22eさんが紹介してくださっているので割愛します。

qiita.com

モデルを監視してCRUD操作を検知する思想なので、モデル単位でのログ抑制は設定で可能です。

ただ今回はユーザー種別の場合にログを抑制したいというニーズがあり、やり方が分からなかったので技術検証してみます。

ChatGPTに聞いてみた

前提としてググってもdjango-auditlogの発展的な使い方に関する情報はほとんど見つかりませんでした。

目ぼしいものは8年前のものですが以下のStack Overflowの記事くらいでした。この記事も前提となるDjangoのバージョンが1.8かつdjango-auditlogも2023年に3系にメジャーバージョンアップしているのでそのまま使える情報ではなさそうです。

stackoverflow.com

ChatGPTに聞いてみたところ、以下のような回答でした。

ChatGPTの回答

①カスタム Middleware を定義する

your_app/middleware.py

from auditlog.middleware import AuditlogMiddleware

class CustomAuditlogMiddleware(AuditlogMiddleware):
    def get_user(self, request):
        user = super().get_user(request)

        # 例: User モデルに user_type フィールドがある場合
        if getattr(user, 'user_type', None) in ['system', 'batch']:
            return None  # ログに記録しないようにする

        return user

settings.pyで Middleware を差し替える

MIDDLEWARE = [
    # 'auditlog.middleware.AuditlogMiddleware',  ← 削除
    'your_app.middleware.CustomAuditlogMiddleware',  # ← 追加
    # その他のミドルウェア
]

AuditlogMiddleware_get_actorのオーバーライドを試す

ChatGPTの回答の裏取りで最新のAuditlogMiddlewareソースコードをみてみたところ、get_userというメソッドはありませんでしたが、恐らく_get_actorのことを指しているのだろうと読み替えました。

github.com

以下のように_get_actorをオーバーライドして、元の実装に追加でuser.is_staff = Trueの場合はNoneを返すようにしてみました。

from auditlog.middleware import AuditlogMiddleware
from django.contrib.auth import get_user_model

class CustomAuditlogMiddleware(AuditlogMiddleware):
    
    @staticmethod
    def _get_actor(request):
        user = getattr(request, "user", None)
        if not isinstance(user, get_user_model()):
            return None
        if not user.is_authenticated:
            return None
        if user.is_staff:
            return None
        return None

結果

USERsystemとなっただけでログは作成されてしまい、期待通りの挙動にはなりませんでした。

_get_actorNoneを返した場合、USERsystemになるだけでログ自体は作成される仕様のようです。

AuditlogMiddleware__call__のオーバーライドを試す①

AuditlogMiddlewareをオーバーライドする方針はそのままで、__call__の方を以下のようにオーバーライドしてみました。

from auditlog.middleware import AuditlogMiddleware
from auditlog.cid import set_cid
from auditlog.context import set_actor

class CustomAuditlogMiddleware(AuditlogMiddleware):
    
    def __call__(self, request):
        remote_addr = self._get_remote_addr(request)
        remote_port = self._get_remote_port(request)
        user = self._get_actor(request)

        if user and user.is_staff: # 追加: ユーザーがスタッフの場合は監査ログを抑制する
            return self.get_response(request)

        set_cid(request)

        with set_actor(actor=user, remote_addr=remote_addr, remote_port=remote_port):
            return self.get_response(request)

結果

これでもUSERsystemとなっただけでログは作成されてしまい、期待通りの挙動にはなりませんでした。

set_actorはあくまでログに操作したユーザーの情報を付与するだけの役割であって、with set_actorを実行しないようにするだけではログは抑制できないようです。

https://django-auditlog.readthedocs.io/en/latest/usage.html#set-actor

AuditlogMiddleware__call__のオーバーライドを試す②

公式ドキュメントをみていたらset_actorと同様にwithブロックで使えるdisable_auditlogという関数を発見しました。

https://django-auditlog.readthedocs.io/en/latest/usage.html#disable-auditlog

__call__の中でこれを実行するようにしてみます。

from auditlog.middleware import AuditlogMiddleware
from auditlog.cid import set_cid
from auditlog.context import set_actor, disable_auditlog # disable_auditlogのインポートを追加

class CustomAuditlogMiddleware(AuditlogMiddleware):
    
    def __call__(self, request):
        remote_addr = self._get_remote_addr(request)
        remote_port = self._get_remote_port(request)
        user = self._get_actor(request)

        if user and user.is_staff: # ユーザーがスタッフの場合は監査ログを抑制する
            with disable_auditlog():
                return self.get_response(request)

        set_cid(request)

        with set_actor(actor=user, remote_addr=remote_addr, remote_port=remote_port):
            return self.get_response(request)

結果

この方法でuser.is_staff = Trueの場合にログを抑制することに成功しました。




以上の内容はhttps://kamatimaru.hatenablog.com/entry/2025/06/23/003719より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14