DjangoでDateTimeFieldチェックがフォーマットエラーになってしまう場合の対応
DjangoでDateTimeFieldチェックがフォーマットエラー(バリデーションエラー)になってしまう場合の対応方法をご紹介します。
目次
条件
- Django 2.2.3
- Python 3.7.0
事象
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



