動機
django-auditlog には log_create method があるものの、 bulk_create には対応していないので...と思ったのだが、 delete() は QuerySet に発行しても signal があるのか LogEntry が作られていて、結果このコードはいらなかった。他で使うかもなのでいったんおいておく
調査方法
- 実際に1件対象のモデルを削除してみる →
LogEntryの各フィールドにどんな値が入ってるか確認 - ライブラリソースコードを見る
方針
changes の作成とか remote_addr の取得とかは独自でロジックを組まずに、すでに実装されてるメソッドを使った。ドキュメントされてないメソッド使うのどうなんという気持ちと、あんまりリッチなドキュメントでもないからまあええか、のきもち。
https://github.com/jazzband/django-auditlog/blob/master/auditlog/diff.py#L117
sample code
from datetime import datetime from auditlog.diff import model_instance_diff from auditlog.middleware import AuditlogMiddleware from auditlog.models import LogEntry from django.contrib.contenttypes.models import ContentType request = {} # TODO: pass django.HttpRequest object JST = None # TODO: pass timezone object log_entries = [] for item in items: log_entry = LogEntry( content_type=ContentType.objects.get_for_model(item), object_id=item.id, object_pk=f"{item.id}", object_repr=str(item), action=LogEntry.Action.DELETE, changes=model_instance_diff(item, None), actor=AuditlogMiddleware._get_actor(request), remote_addr=AuditlogMiddleware._get_remote_addr(request), timestamp=datetime.now(JST), ) log_entries.append(log_entry) LogEntry.objects.bulk_create(log_entries)
余談: delete() の signal について
ごりごり docs に書いてあって、
It does, however, emit the pre_delete and post_delete signals for all deleted objects (including cascaded deletions).
delete() は update() bulk_update() bulk_create() と違って signal を発火してくれるとのこと。わら。