Django form.instance.field displaying incorrect datetime value on HTML template despite having the correct value at hand

I'm running Django 4.1, and the view that serves the template is a FormView-child.

To start off with, here's the canonical answer as to what the correct value is, taken directly from the database:

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

The first HTML template invocation of that same field:

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

And the result is as expected:

enter image description here

About 30 lines of code below (none of which do anything particularly functional, it's just a boatload of div declarations for CSS and styling), inside a <form>, on a modal:

<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>

And now, prepare for the result - which also highlights the question I am about to get to:

enter image description here

What in Django's ghost in the shell is going on? How did 2023-01-24 become 2023-01-01 for no apparent reason? Or said differently, why and how can the same context invocation have two different values in the same render of the same template?

I would very much like for the second invocation to show the correct value - meaning the value that is both in the database, and presumably also in the context (since it's showing the correct value before the modal is opened).

Things that do not work:

  • Reload (F5)
  • Force reload (Shift+F5)
  • Relaunching the server
  • Force updating the database value for that field to a different date

To make matters worse, the value apparently is correct even when it's not - or so the developer console says. The date is different from 2023-01-24 because this screenshot was taken after I updated the date manually, as mentioned in the list of things that did not work:

enter image description here

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

So at the end of this all, what is happening that makes ... something, whether it's Django or something else, render the value of 2023-01-24 as 2023-01-01 in one instance but not in the other?

I had basically spent an hour writing this question before I stumbled upon what I almost instantly realized would lead to the solution at the end of the post, so given the effort spent I'll post and self-answer.

It would appear that Django picked a string format when it came time to transmit the datetime object to the browser, and when trying to populate the date-picker element with this predetermined value, we discover that the browser doesn't understand dates in the MMM-DD-YYYY format.

Changing the problematic invocation thusly solved the issue:
value="{{ form.instance.appreciation_date|date:'Y-m-d'}}"

The explanation of why this work is roundaboutly as follows:

Tacking on |date:'Y-m-d' uses Django's built-in date filter to format the datetime object before any values are actually rendered into the HTML file.

Back to Top