\ ポイント最大47倍! /

【Django】auto_now_addとauto_nowの違いについて

  • DatetimeFieldの現在日時設定用のプロパティを解説して!

このような疑問にお答えします。

DateTimeFieldには以下のプロパティが用意されています。

  • auto_now_add
  • auto_now

auto_now_addは新しく追加されたタイミングの時刻を自動的に追加します。

一方で、auto_nowは更新のたびに現在時刻を設定するプロパティです。

パッと見ではどれがどっちか分からなくなってしまうので、本記事で整理しておきましょう。

auto_now_addとauto_nowの違いについて

どちらも日時を自動的に取得して保存するものです。

auto_nowauto_now_addを使うと、プログラム内から直接値を設定できなくなります。

手動で値を設定する必要がある場合はdefaultを使用するか、別の方法でフィールドを定義することになります。

具体的な設定例

作成日と更新日だけを設定したモデルを例示します。

from django.db import models


class ExampleModel(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)  # 作成日時
    updated_at = models.DateTimeField(auto_now=True)  # 更新日時

    class Meta:
        ordering = ["-created_at"]  # デフォルトの並び順(最新が上)

    def __str__(self):
        return f"ExampleModel created on {self.created_at}"

今回説明するのは、DateTimeFieldに設定したauto_now_addとauto_nowの二つです。

auto_now_add=Trueについて

インスタンスの作成時に、一度だけ日時を設定したいとき用のものです。

作成日時は、このauto_now_add=Trueとすることが多いかと思います。

auto_now=Trueについて

インスタンスが更新されるたびに、自動的に現在日時を取得します。

つまり、更新日時を表すupdated_atなどのフィールドに多く使われます。

auto_now / auto_now_add の補足知識

ここからは両者の理解を深めるために、それぞれのプロパティを少し突っ込んで解説します。

二つのプロパティが分かれている理由

以下の二つを区別して、簡潔に扱うためです。

  • 作成時のタイムスタンプ
  • 更新時のタイムスタンプ

どのタイミングでタイムスタンプが反映されるかが一目でわかります。

注意点

auto_now, auto_now_addを使うと、手動で値を設定することができません。

もし手動設定したい場合には、defaultか他の方法でフィールドを定義する必要があります。

補足: タイムスタンプは抽象基底クラスで一括管理するのがベスト

Django では「作成日時(created_at)」と「更新日時(updated_at)」を ほぼすべてのモデルで使う場面が出てきます。

でも、各モデルに次のようなフィールドを毎回書くのは非効率です。

Python
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
  • コピペが増える
  • 書き忘れが起こる
  • モデルによって仕様が揃わなくなる

こうした問題を避けるために、タイムスタンプは 抽象基底クラス(abstract base class)で共通化するのが実務で最もよく使われる方法です。

共通の TimeStampedModel を作る

Python
from django.db import models

class TimeStampedModel(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)  # レコード作成日時を自動保存
    updated_at = models.DateTimeField(auto_now=True)      # レコード更新日時を自動更新

    class Meta:
        abstract = True  # このクラス自体はDBにテーブルを作らない

各モデルでは継承するだけで OKです。

Python
class Article(TimeStampedModel):
    title = models.CharField(max_length=255)
    content = models.TextField()

これだけで、どのモデルにも created_at / updated_at が保証されるようになります。

この方法により、次のメリットがあります。

  • モデルごとにタイムスタンプを書かなくて済む(DRY)
  • 書き忘れゼロでデータの一貫性が保たれる
  • 全モデルの仕様が揃うため保守しやすい
  • どんなアプリでもほぼ必須のパターンとして使える

Django アプリを中規模以上で運用するならTimeStampedModel を定義しておくのは本当に便利です。

この記事が気に入ったら
フォローしてね!

シェア・記事の保存はこちら!

この記事を書いた人

CFXLOGのアバター CFXLOG プログラマ

メイン言語はPython。本ブログでは、実務や普段の学習で学んだことをアウトプットしています。
基本情報技術者試験合格者。

コメント

コメントする

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)