Opened 20 months ago
Last modified 20 months ago
#35314 closed Bug
Django 5 breaks value of Date field rendering correctly in template — at Initial Version
| Reported by: | Michael | Owned by: | nobody |
|---|---|---|---|
| Component: | Forms | Version: | 5.0 |
| Severity: | Normal | Keywords: | form date |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
This used to work correctly in Django 4. Django 5 removed USE_L10N setting from settings.py
When rendering an input field that is of type date:
/home/michael/.venv/project/lib/python3.11/site-packages/django/forms/boundfield.py(108)as_widget() -> return widget.render( /home/michael/.venv/project/lib/python3.11/site-packages/django/forms/widgets.py(279)render() -> context = self.get_context(name, value, attrs) /home/michael/.venv/project/lib/python3.11/site-packages/django/forms/widgets.py(332)get_context() -> context = super().get_context(name, value, attrs) /home/michael/.venv/project/lib/python3.11/site-packages/django/forms/widgets.py(271)get_context() -> "value": self.format_value(value), /home/michael/.venv/project/lib/python3.11/site-packages/django/forms/widgets.py(555)format_value() -> value, self.format or formats.get_format(self.format_key)[0]
We that formats.get_format(self.format_key) only passes in 1 argument to:
# django/utils/formats.py(109)get_format()
def get_format(format_type, lang=None, use_l10n=None):
"""
For a specific format type, return the format for the current
language (locale). Default to the format in the settings.
format_type is the name of the format, e.g. 'DATE_FORMAT'.
If use_l10n is provided and is not None, it forces the value to
be localized (or not), otherwise it's always localized.
"""
if use_l10n is None:
use_l10n = True
if use_l10n and lang is None:
lang = get_language()
format_type = str(format_type) # format_type may be lazy.
cache_key = (format_type, lang)
try:
return _format_cache[cache_key]
except KeyError:
pass
this means use_l10n initial value is None, which means it will be set to True via the logic:
if use_l10n is None:
use_l10n = True
So then it sets a language, in my case en-gb, which makes results in a cache_key of ('DATE_INPUT_FORMATS', 'en-gb')
Which means the get_format method returns ['%d/%m/%Y', '%d/%m/%y', '%Y-%m-%d']
Which is really bad when format_type = 'DATE_INPUT_FORMATS', because HTML inputs must always be in the format YYYY/MM/DD, and hence selecting the first format of %d/%m/%Y results in an error in your HTML template when your input is rendered like <input type="date" value="31/12/2024"> instead of <input type="date" value="2024/12/31">
Not that it changes anything, but here is my DATE_INPUT_FORMATS from settings.py (it has no USE_L10N setting as unfortunately that has been removed):
DATE_INPUT_FORMATS = [
'%Y-%m-%d',
]