Opened 2 years ago

Closed 2 years ago

#34004 closed Bug (invalid)

DateTimeField for Forms does not always respect input_formats

Reported by: Emily Hontoria Owned by: nobody
Component: Forms Version: 3.1
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When creating a new form with a single DateTimeField and supplying a string formatted datetime (for example "2021-12-10 10:00:00") the form is considered valid even if the given datetime is not in a supported input_formats.

Relevant doc: https://docs.djangoproject.com/en/3.2/ref/forms/fields/#datetimefield

Small reproducible snippet:

        test_sets = [
            # Missing seconds
            {"input_format": "%Y-%m-%d %H:%M:%S", "dt": "2018-12-10 21:00"},
            # Hour in 24 format instead of 12
            {"input_format": "%Y-%m-%d %I:%M", "dt": "2018-12-10 21:00"}
        ]

        for incorrect_pair in test_sets:
            dt_val = incorrect_pair["dt"]
            input_format_val = incorrect_pair["input_format"]

            class DateTimeFormTester(forms.Form):
                dt = forms.DateTimeField(input_formats=[incorrect_pair["input_format"]])

            test_form = DateTimeFormTester({"dt": incorrect_pair["dt"]})
            if test_form.is_valid():
                print(f"Incorrectly determined {dt_val} as valid for input_format {input_format_val}")

Was not a problem in Django 3.0.14, can reproduce in Django 3.1.14 with the above snippet.

I believe the problem stems from this bit of code in django.forms.fields:

        try:
            result = parse_datetime(value.strip())
        except ValueError:
            raise ValidationError(self.error_messages['invalid'], code='invalid')
        if not result:
            result = super().to_python(value)

which means that if we are able to parse_datetime we never run super().to_python(value) which is what checks the format is correct.

Change History (1)

comment:1 by Mariusz Felisiak, 2 years ago

Resolution: invalid
Status: newclosed
Summary: Bug: DateTimeField for Forms does not always respect input_formatsDateTimeField for Forms does not always respect input_formats

This was changed in Django 3.1 (see 1487f16f2d29c7aeaf48117d02a1d7bbeafa3d94 and #11385). It's also documented:

"The field always accepts strings in ISO 8601 formatted dates or similar recognized by parse_datetime()"

Changed in Django 3.1:

Support for ISO 8601 date string parsing (including optional timezone) was added.

Note: See TracTickets for help on using tickets.
Back to Top