Opened 3 years ago
Closed 3 years ago
#33066 closed Cleanup/optimization (wontfix)
Add annotation about accepting ISO 8601 formats by DateTimeField() to the DATETIME_INPUT_FORMATS docs.
Reported by: | Christian Reksten-Monsen | Owned by: | nobody |
---|---|---|---|
Component: | Documentation | Version: | 3.2 |
Severity: | Normal | Keywords: | datetime iso8601 |
Cc: | Claude Paroz | Triage Stage: | Unreviewed |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
According to the documentation on DATETIME_INPUT_FORMATS, the given list of date time formats will be accepted when inputting data on a datetime field. My assumption is that Django will ONLY accept formats from this list (and also DATE_INPUT_FORMATS, as mentioned in the docs). Django will, however, also accept ISO 8601 date inputs, even though these formats are not present in DATETIME_INPUT_FORMATS. This is not mentioned in the docs.
This is because of PR #11893 for ticket 11385 which added support for ISO 8601 date inputs. ISO 8601 matching is done in DateTimeField and if there is a match, the BaseTemporalField to_python method (which checks date time format against DATETIME_INPUT_FORMATS) is never called.
This was confusing for me when unit testing a form field, a validation error was not raised when giving a date format that was not present in DATETIME_INPUT_FORMATS. Below test case replicates the issue.
Possible solutions:
- Add the date time format (with timezone format, which I believe was the issue) to DATETIME_INPUT_FORMATS default. Python 2.7 and 3 strptime() do support %z.
- Ignore it and update the docs that ISO 8601 date time formats will be accepted, regardless of not being present in DATETIME_INPUT_FORMATS.
- Set a flag to strictly adhere DATETIME_INPUT_FORMATS or also allow ISO 8601 date time formats.
from datetime import datetime from django.core.exceptions import ValidationError from <app_name>.settings import DATETIME_INPUT_FORMATS from django.test import TestCase class TestDateTimeField(TestCase): def test_field_validation(self): with self.settings(DATETIME_INPUT_FORMATS=['%d/%m/%Y %H:%M']): field = DateTimeField(required=True) self.assertIsInstance(field.clean("31/12/2021 14:30"), datetime) with self.assertRaises(ValidationError): field.clean("2021-12-31 14:30")
Change History (3)
comment:1 by , 3 years ago
comment:2 by , 3 years ago
Component: | Forms → Documentation |
---|---|
Type: | Bug → Cleanup/optimization |
comment:3 by , 3 years ago
Cc: | added |
---|---|
Resolution: | → wontfix |
Status: | new → closed |
Summary: | DateTimeField does not exclusively validate the date time format against DATETIME_INPUT_FORMATS → Add annotation about accepting ISO 8601 formats by DateTimeField() to the DATETIME_INPUT_FORMATS docs. |
Thanks for the ticket, however this change is related with DateTimeField
not with the DATETIME_INPUT_FORMATS
setting itself, its docs are still valid. We normally don't include such versionchanged
annotations and I don't think this case is somehow special.
Reading the docs on form DateTimeField, its seems that the intended functionality is for the field to always accept ISO formats.
I therefore suggest to add clarification on this to the DATETIME_INPUT_FORMAT docs. Maybe just simply adding below text to the Changed in Django 3.1 callout:
I have modified this ticket to reflect this being a documentation cleanup.