【Django】bulk 処理では save メソッドが実行されない

django

Django の bulk 処理 (bulk_create, bulk_update) では save メソッドが実行されません。

そのため、DateTimeField の auto_now など save で行っている自動更新処理は実行されないため注意が必要です。

save 処理と bulk 処理を少しだけ共通化できる処理を紹介です。

一例ですが参考になればと思います。

以下記事の処理を使用しています。

処理の紹介

# models.py
import datetime
from django.db import models
from django_currentuser.middleware import get_current_authenticated_user

class BaseModel(modles.Model):
    create_at = models.DateTimeField(blank=False, null=False, auto_now_add=True)
    create_user_id = models.BigIntegerField(blank=False, null=False)
    update_at = models.DateTimeTimeFiled(blank=False, null=False, auto_now=True)
    update_user_id = models.BigIntegerField(blank=False, null=False)

    def save(self, *args, editor: int = None, **kwargs):
        self.set_auto_field(editor=editor)
        super().save(*args, **kwargs)

    def set_auto_field(self, editor: int = None, set_now: bool = False):
        if editor:
            id = editor
        else:
            # ログインユーザーIDを取得
            id = get_current_authenticated_user().id
        
        if not self.create_user_id:
            self.create_user_id = id
        self.update_user_id = id

        if set_now:
            now = datetime.datetime.now()
            if now self.create_at:
                self.create_at = now
            self.update_at = now
        
        class Meta:
            abstract = True

使い方

以下のように使います。

# models.py
class Sample(BaseModel):
    name = models.CharField(max_length=100)

# 実装.py
def do_insert(self, data, editor: int = None, is_bulk: bool = False):
    m = Sample()

    # 値をセット
    ...

    if is_bulk:
        # bulk のときは自動フィールドをセットして返却
        m.set_auto_field(editor=editor, set_now=True)
    else:
        # bulk 以外はそのまま保存
        m.save(editor=editor)

    return m

あとはこの処理を呼びたい処理が bulk を使いたいかによって良いように呼びだします。

他には bulk_create などを拡張し根本的に対応するなどが考えられますが、コスト的に自分ができる最良の方法を考えた結果がこれでした。

もっといいやり方があれば学んでいきたいところです。

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