Hi everyone,
I’m sorry I can’t open a topic with more than 2 links here, but it follows a detailed research that I did after the suggestion from Jacob in a ticket I opened a few weeks ago.
I created a blog article with the full explanation here on my website. Markdown version available if someone wants to update/recreate the post with all the research references.
TLDR if you don’t want to open the link to the blog post
New opt-in setting USE_HTML5_DATE_INPUT (default False) that makes DateInput, TimeInput, and DateTimeInput render native <input type="date/time/datetime-local"> instead of <input type="text">. Browser support is now ~97% globally (including Safari since 2021). It’s fully backwards-compatible: off by default, overridable per-widget, and the admin’s JS calendar gracefully defers to native pickers. Accessibility is at least on par with the existing JS widgets (which just got improved via #36459 and #36458). Main win is touch/mobile UX with platform-native pickers.
I’d appreciate feedback on the approach.
Thanks,
Denny
4 Likes
Hi!
Thanks for looking at this. For a few projects over the past 5 years, I’ve used native <input type=date> and friends, with custom widget subclasses. I think we’re ready to provide support in Django, but I’m not 100% sure on the plan to only provide a global setting that switches all forms over. Global switches are great for opting-in on new projects, but they’re not a useful tool for migrating existing codebases, where one often needs per-field control.
Additionally, BaseTemporalField (the base for DateField and friends), currently validates against locale-based formats, while <input type=date> and co. only send ISO8601 values. Your proposal has these keep working, but I think it would be best to avoid having unused parsing logic.
I think a gentler, more targeted plan would be better. The first release could do something like:
- Add
NativeDateInput, NativeTimeInput, and NativeDateTimeInput widget classes (names to be bikeshedded).
- Add
NativeDateField etc. that use these widgets by default.
- Move the admin to use them, rather than its custom widgets, with a per-
ModelAdmin (?) option to switch back. (We can be more aggressive with the admin, as it’s a UI that we fully control.)
- Document how to use
ModelFormOptions.formfield_callback to switch your forms to use the native fields.
We could also consider a global switch that changes the defaults for forms to native fields, but given there would be a snippet to copy for your base field class, that could wait for a later release, when any rough edges have been tested.
What do you think?
3 Likes
Well the main problem is keeping compatibility with the previous use case (with type="text) without breaking existing things.
I know that we can be more aggressive with the admin, but those templates can be extended as well by users, so maybe still not too aggressive 
I can change the implementation using different widget classes instead of the current ones, not a big problem, but then we’d have multiple classes that implement (almost) the same thing.
Referring to my current (wip)implementation I can also create those classes like:
# unchanged
class DateInput(DateTimeBaseInput):
format_key = "DATE_INPUT_FORMATS"
template_name = "django/forms/widgets/date.html"
# extending the base one adding html5 attributes
class NativeDateInput(DateInput):
html5_input_type = "date"
html5_format = "%Y-%m-%d"
so we can reuse the base logic adding the new input_type only there, or just
class NativeDateInput(DateInput):
input_type = "date"
html5_format = "%Y-%m-%d"
def format_value(self, value):
return formats.localize_input(value, "%Y-%m-%d")
Let’s see what others think, I tried to do something years ago related to this, but then there was no basic consensus and everyone “steering the wheel” on a different side, so I dropped everything because life happens 
I think that now it’s time to improve this, to step into the future present