#35314: Django 5 breaks value of Date field rendering correctly in template
---------------------------+--------------------------------------
Reporter: Michael | Owner: nobody
Type: Bug | Status: new
Component: Forms | Version: 5.0
Severity: Normal | Resolution:
Keywords: form date | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
---------------------------+--------------------------------------
Description changed by Michael:
Old 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',
> ]
> }}}
New 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 see 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',
]
}}}
--
--
Ticket URL: <https://code.djangoproject.com/ticket/35314#comment:1>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/0107018e51dc23a8-a34471af-9778-4e97-a3c3-b54e887bf5e6-000000%40eu-central-1.amazonses.com.