【Django】テーブル更新時にユーザーIDを自動で保存する

django

テーブル定義に作成者や更新者のフィールドを持つことがあると思います。

データの追加、更新時に毎回更新する必要があり、処理を実装するたびに毎回記述するのはコストが掛かる点と実装漏れ等の観点から処理を統一することが望まれます。

そのため、 Django において DB 保存時に日時を自動更新する方法について説明します。

model でユーザーIDを取得

今回は model でユーザーIDを取得するのに外部パッケージを使います。

django-currentuser | pypi.org

ログインユーザーを 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 では設定されませんので注意が必要です。

タイトルとURLをコピーしました