サイトアイコン 知的好奇心

DjangoでDateTimeFieldチェックがフォーマットエラーになってしまう場合の対応

DjangoでDateTimeFieldチェックがフォーマットエラー(バリデーションエラー)になってしまう場合の対応方法をご紹介します。

条件

事象

DateTimeFieldの日時フォーマットチェックにおいて、自分で指定したフォーマットで入力したのにも関わらず、入力チェックに引っかかりエラーになる場合があります。

例:django-bootstrap-datepicker-plusの場合

OKケース

「format=’%Y-%m-%d’」とすると問題なく入力チェックが通ります。

class CreateView(generic.edit.CreateView):
    model = Question
    fields = ['question_text', 'pub_date']
    def get_form(self):
        form = super().get_form()
        form.fields['pub_date'].widget = DateTimePickerInput(format='%Y-%m-%d')
        return form

NGケース

「format=’%Y/%m/%d’」とすると必ずバリデーションエラーになります。

class CreateView(generic.edit.CreateView):
    model = Question
    fields = ['question_text', 'pub_date']
    def get_form(self):
        form = super().get_form()
        form.fields['pub_date'].widget = DateTimePickerInput(format='%Y/%m/%d')
        return form

原因

Djangoの日時チェックで使用される「DATETIME_INPUT_FORMATS」に「’%Y/%m/%d’」が無いのが原因です。

上記のOKケースの「%Y-%m-%d」は「DATETIME_INPUT_FORMATS」に定義済みです。

django\conf\global_settings.py抜粋

DATETIME_INPUT_FORMATS = [
    '%Y-%m-%d %H:%M:%S',     # '2006-10-25 14:30:59'
    '%Y-%m-%d %H:%M:%S.%f',  # '2006-10-25 14:30:59.000200'
    '%Y-%m-%d %H:%M',        # '2006-10-25 14:30'
    '%Y-%m-%d',              # '2006-10-25'
    '%m/%d/%Y %H:%M:%S',     # '10/25/2006 14:30:59'
    '%m/%d/%Y %H:%M:%S.%f',  # '10/25/2006 14:30:59.000200'
    '%m/%d/%Y %H:%M',        # '10/25/2006 14:30'
    '%m/%d/%Y',              # '10/25/2006'
    '%m/%d/%y %H:%M:%S',     # '10/25/06 14:30:59'
    '%m/%d/%y %H:%M:%S.%f',  # '10/25/06 14:30:59.000200'
    '%m/%d/%y %H:%M',        # '10/25/06 14:30'
    '%m/%d/%y',              # '10/25/06'
]

対応方法

settings.pyを以下のように記述します。

USE_L10N = False # DATETIME_INPUT_FORMATSに変更を加えるため、Falseに設定 

from django.conf.global_settings import DATETIME_INPUT_FORMATS  # 追加

DATETIME_INPUT_FORMATS += ('%Y/%m/%d',)  # 追加

「DATETIME_INPUT_FORMATS」に存在しないフォーマットを追加することで、日時チェックが通るようになります。

追記

settings.pyを以下のような設定にしても、日時チェックが通るようです。

LANGUAGE_CODE = 'ja-jp'

TIME_ZONE = 'Asia/Tokyo'

USE_I18N = True

USE_L10N = True

USE_TZ = False

from django.conf.global_settings import DATETIME_INPUT_FORMATS

DATETIME_INPUT_FORMATS += ('%Y/%m/%d',)

参考

djangoドキュメント:django.forms.fields のソースコード

https://docs.djangoproject.com/ja/2.2/_modules/django/forms/fields/

How to Extend Django DATETIME_INPUT_FORMATS Setting

https://stackoverflow.com/questions/27215961/how-to-extend-django-datetime-input-formats-setting

django DATETIME_INPUT_FORMATS not working

https://stackoverflow.com/questions/33177707/django-datetime-input-formats-not-working

モバイルバージョンを終了