auto_now_addとauto_nowの活用方法
Djangoフレームワークでは、オブジェクトの作成日時と更新日時を自動で管理するためにauto_now_add=Trueとauto_now=Trueという便利な機能が提供されています。これらの具体的な使用方法と相違点について以下に説明します。
auto_now_add=Trueの特性
- 動作: オブジェクトが初めて作成される際に、そのフィールドに現在の日時を自動的に設定します。
- 適用場面: オブジェクトの作成日時を記録する必要があるが、その後は変更されないようにしたいフィールドに適しています。
auto_now=Trueの特性
- 動作: オブジェクトが保存されるたびに、そのフィールドに現在の日時を自動的に設定します。
- 適用場面: オブジェクトの最終更新日時を追跡する必要があるフィールドに適しており、オブジェクトが変更されるたびにタイムスタンプが更新されます。
比較と違い
auto_now_add=True:- オブジェクト作成時にのみ自動で値が設定されます。
- 作成後はフォームや管理画面から変更できず、作成時刻の正確性が保証されます。
- 作成日時フィールドの処理を簡素化します。
default=now:- より柔軟性があり、オブジェクトインスタンス化時に初期値を手動で設定できます。
editable=Falseと組み合わせることで、フォームからの手動編集を防ぎます。- 初期時刻を手動で設定する必要がある場合に有用ですが、通常は
auto_now_addほどシンプルではありません。
推奨される使用方法
ほとんどの場合、作成日時と更新日時の管理にはauto_now_add=Trueとauto_now=Trueを使用することが推奨されます。これらは意図が明確で使いやすいためです。
実装例
以下にAuditBaseModelでこれらの属性を使用する方法を示します。
監査モデルと承認モデルの定義
from django.conf import settings
from django.db import models
from core.models import MasterModel
class ApprovalBaseModel(models.Model):
reference_no = models.ForeignKey(MasterModel, null=True, blank=True, to_field='reference_number',
on_delete=models.PROTECT, related_name='%(class)s_reference',
verbose_name="承認番号")
approval_status = models.BooleanField(default=False, verbose_name='承認状態')
reviewer = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT, null=True, blank=True,
to_field='username', related_name='%(class)s_reviewer', verbose_name='レビュアー')
review_time = models.DateTimeField(null=True, editable=False, blank=True, verbose_name="承認日時")
class Meta:
abstract = True
from django.utils.timezone import now
class AuditBaseModel(models.Model):
creator = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT, null=True, blank=True,
to_field='username', related_name='%(class)s_creator', verbose_name='作成者')
created_time = models.DateTimeField(auto_now_add=True, verbose_name="作成日時")
modifier = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT, null=True, blank=True,
to_field='username', related_name='%(class)s_modifier', verbose_name="更新者")
modified_time = models.DateTimeField(auto_now=True, verbose_name="更新日時")
class Meta:
abstract = True
class SalesOrderClosureModel(ApprovalBaseModel, AuditBaseModel):
"""
売上注文クローズモデルヘッダー
未出荷または部分出荷の場合、この注文をクローズし、実際に出荷された数量を計上します
"""
closure_no = models.CharField(unique=True, max_length=20, editable=False, verbose_name="クローズ番号")
closure_date = models.DateField(default=date.today, editable=False, verbose_name="クローズ日")
factory = models.ForeignKey(FactoryModel, on_delete=models.PROTECT, related_name='sales_factory',
to_field='factory_code', verbose_name="工場")
customer = models.ForeignKey(CustomerModel, on_delete=models.PROTECT, related_name='sales_customer',
to_field='customer_code', verbose_name="顧客")
representative = models.ForeignKey(RepresentativeModel, on_delete=models.PROTECT,
related_name='sales_rep', to_field='rep_code',
verbose_name="担当者")
reason = models.CharField(null=True, blank=True, max_length=100, verbose_name="クローズ理由")
is_confirmed = models.BooleanField(default=False, verbose_name="確認状態")
confirm_user = models.CharField(max_length=20, editable=False, null=True, blank=True,
verbose_name="確認ユーザー")
confirm_time = models.DateTimeField(null=True, editable=False, blank=True, verbose_name="確認日時")
class Meta:
db_table = 'sales_closure'
verbose_name = '売上注文クローズヘッダー'
verbose_name_plural = verbose_name