概要
django-auditlogというjazzbandの管轄のDjangoのモデル操作の監査ログを作成してくれるライブラリがあります。
基本的な使い方は以下の記事でryu22eさんが紹介してくださっているので割愛します。
モデルを監視してCRUD操作を検知する思想なので、モデル単位でのログ抑制は設定で可能です。
ただ今回はユーザー種別の場合にログを抑制したいというニーズがあり、やり方が分からなかったので技術検証してみます。
ChatGPTに聞いてみた
前提としてググってもdjango-auditlogの発展的な使い方に関する情報はほとんど見つかりませんでした。
目ぼしいものは8年前のものですが以下のStack Overflowの記事くらいでした。この記事も前提となるDjangoのバージョンが1.8かつdjango-auditlogも2023年に3系にメジャーバージョンアップしているのでそのまま使える情報ではなさそうです。
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のことを指しているのだろうと読み替えました。
以下のように_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
結果
USERがsystemとなっただけでログは作成されてしまい、期待通りの挙動にはなりませんでした。

_get_actorがNoneを返した場合、USERがsystemになるだけでログ自体は作成される仕様のようです。
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)
結果
これでもUSERがsystemとなっただけでログは作成されてしまい、期待通りの挙動にはなりませんでした。

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の場合にログを抑制することに成功しました。