Django form.instance.field отображает неверное значение даты в HTML-шаблоне, несмотря на наличие правильного значения под рукой

Я запускаю Django 4.1, и представление, которое обслуживает шаблон, является FormView-child.

Для начала, вот канонический ответ о том, какое значение является правильным, взятый непосредственно из базы данных:

In [6]: DCF.objects.last().appreciation_date
Out[6]: datetime.date(2023, 1, 24)

Первый вызов шаблона HTML для этого же поля:

<h5>Title: {{ form.instance.appreciation_date }}</h5>

И результат соответствует ожиданиям:

enter image description here

Около 30 строк кода ниже (ни одна из которых не делает ничего особенно функционального, это просто куча объявлений div для CSS и стилизации), внутри <form>, на модале:

<div class="mb-3">
    <label for="{{ form.appreciation_date.id_for_label }}">Date</label>
    <input class="form-control datepicker" placeholder="Please select date" type="text" onfocus="focused(this)" onfocusout="defocused(this)" name="{{ form.appreciation_date.name }}" value="{{ form.instance.appreciation_date }}">
</div>

А теперь приготовьтесь к результату - который также освещает вопрос, к которому я собираюсь перейти:

enter image description here

Что происходит с призраком Джанго в оболочке? Как 2023-01-24 превратилось в 2023-01-01 без видимой причины? Или, говоря иначе, почему и как один и тот же контекстный вызов может иметь два разных значения в одном и том же рендере одного и того же шаблона?

Я бы очень хотел, чтобы во втором вызове было показано правильное значение - имеется в виду значение, которое находится как в базе данных, так и, предположительно, в контексте (поскольку оно показывает правильное значение до открытия модала).

То, что не работает:

  • Перезагрузка (F5)
  • Принудительная перезагрузка (Shift+F5)
  • Перезапуск сервера
  • Принудительное обновление значения базы данных для этого поля на другую дату

Еще хуже то, что значение, по-видимому, является правильным, даже если это не так - или так говорит консоль разработчика. Дата отличается от 2023-01-24, потому что этот снимок экрана был сделан после того, как я обновил дату вручную, как указано в списке того, что не сработало:

enter image description here

In [7]: DCF.objects.last().appreciation_date
Out[7]: datetime.date(2023, 1, 25)

Итак, в конце концов, что происходит, что заставляет ... что-то, будь то Django или что-то другое, отображать значение 2023-01-24 как 2023-01-01 в одном случае, но не в другом?

Я практически час писал этот вопрос, прежде чем наткнулся на то, что, как я почти сразу понял, приведет к решению в конце поста, поэтому, учитывая затраченные усилия, я опубликую и отвечу сам.

Похоже, что Django выбрал строковый формат, когда пришло время передать объект datetime браузеру, и при попытке заполнить элемент date-picker этим предопределенным значением, мы обнаруживаем, что браузер не понимает даты в формате MMM-DD-YYYY.

Изменение проблемного вызова таким образом решило проблему:
value="{{ form.instance.appreciation_date|date:'Y-m-d'}}"

Объяснение того, почему это работает, окольным путем выглядит следующим образом:

Включение |date:'Y-m-d' использует встроенный в Django фильтр date filter для форматирования объекта datetime перед тем, как значения будут отображены в HTML-файл.

Вернуться на верх