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 などを拡張し根本的に対応するなどが考えられますが、コスト的に自分ができる最良の方法を考えた結果がこれでした。
もっといいやり方があれば学んでいきたいところです。