テーブル定義に作成者や更新者のフィールドを持つことがあると思います。
データの追加、更新時に毎回更新する必要があり、処理を実装するたびに毎回記述するのはコストが掛かる点と実装漏れ等の観点から処理を統一することが望まれます。
そのため、 Django において DB 保存時に日時を自動更新する方法について説明します。
model でユーザーIDを取得
今回は model でユーザーIDを取得するのに外部パッケージを使います。
ログインユーザーを thread に持つ処理を使えるようになります。
インストール (pip の場合)
pip install django-currentuser
settings.py に記述
# settings.py
…
MIDDLEWARE = [
…
"django_currentuser.middleware.ThreadLocalUserMiddleware",
…
]
…
使い方
以下のような処理でログインユーザーが取得できるようになります。
from django_currentuser.middleware import get_current_authenticated_user
user = get_current_authenticated_user()
model の定義
以下のような基本モデルを定義します。
# models.py
from django.db import models
from django_currentuser.middleware import get_current_authenticated_user
class Sample(models.Model)
create_user_id = models.BigIntegerField(blank=False, null=False) # 作成日時
update_user_id = models.BigIntegerField(blank=False, null=False) # 更新日時
def save(self, *args, editor: int = None, **kwargs):
"""save を拡張"""
if editor:
id = editor
else:
# 認証済みユーザーを取得
id = get_current_authenticated_user().id
if not self.create_user_id:
# 登録時のユーザーID
self.create_user_id = id
# 更新時のユーザーID
self.update_user_id = id
super().save(*args, **kwargs)
この定義では save メソッドに editor パラメータを追加し、外部からでもユーザーIDを指定できるようにしています。
create_user_id フィールドは必須にしているので None = 登録と判断しています。
user_id のフィールドは外部キーにしても問題ありません。
注意点
user_id が必要なので認証機能 (ログイン画面など) を実装したアプリのみが対象です。
認証済みである必要があります。非認証状態では保存処理が呼ばれた場合、エラーになります。
auto_now_add, auto_now は model の save メソッドが実行されたときにのみ処理がされます。
データを登録する create メソッドは内部で save メソッドを実行するため問題ありませんが、一括更新時に使用する bulk_create, bulk_update では設定されませんので注意が必要です。