django modelのDateTimeField DBカラムデフォルト値でWARNING


あけましておめでとうございます。
django を1.7 から 1.9にversionUpしたら、migrationで

(fields.W161) Fixed default value provided.
    HINT: It seems you set a fixed date / time / datetime value as default for this field. This may not be what you want. If you want to have the current date as default, use `django.utils.timezone.now`

というWARNINGメッセージが出力されました。
原因と、対処方法を備忘として、メモします。

参考サイト

“Fixed default value provided” after upgrading to Django 1.8
Django default=datetime.now() in models always saves same datetime after uwsgi reset
Django datetime issues (default=datetime.now())
Time zones | Django documentation | Django
モデルフィールドリファレンス | Django 1.4 documentation

原因

以下の記述が原因でWARNINGが出力されておりました。

# -*- coding: utf-8 -*-
from django.db import models


class Test(models.Model):

    create_date = \
        models.DateTimeField(default=datetime.utcnow())

    update_date = \
        models.DateTimeField(default=datetime.utcnow())

見解

メッセージの通りですが、

models.DateTimeField(default=datetime.utcnow())

の記述では、migrationsのmigrationファイルに、

        migrations.AlterField(
            model_name='xxxTableName',
            name='create_date',
            field=models.DateTimeField(default=datetime.datetime(2015, 12, 26, 19, 46, 4, 718301)),
        ),
が出力され、「migrationファイル生成時に記述が評価され、その時に時間が設定される」 動作をしていました。

対処方法

以下のように、記述を変更したところ、

# -*- coding: utf-8 -*-
from django.db import models
from django.utils.timezone import now


class Test(models.Model):

    create_date = models.DateTimeField(default=now)

    update_date = models.DateTimeField(default=now)

migrationsのmigrationファイルに、

        migrations.AlterField(
            model_name='xxxTableName',
            name='create_date',
            field=models.DateTimeField(default=django.utils.timezone.now),
        )
が出力され、「migrationファイル実行時に記述が評価され、その時に時間が設定される」
記述になっておりました。

その他、わかったこと

以下、postgressでカラム情報を見た結果です。

    Column     |           Type           |                          Modifiers                           
---------------+--------------------------+--------------------------------------------------------------
 id            | integer                  | not null default nextval('xxx_id_seq'::regclass)
 create_date   | timestamp with time zone | not null
 update_date   | timestamp with time zone | not null

djangoで日付型にデフォルト値を付与したとしても、
DB側のデフォルト値は付与されないのですね。
※アプリケーション側で付与しますよ。ということですね。
DBにデフォルト値つけるより、そっちが確実というか、アプリ側でnull設定されると、 デフォルト値つけてても、意味ないからつけていない?
DjangoからINSETするわけではないので、DB的な制約ををつけて欲しかったのですが…

以上です。

コメント