Rendering individual subwidgets for a MultiWidget

Let’s say we have the following form:

from django import forms

class EventForm(forms.Form):
    # ... other fields
    when = forms.DateTimeField(widget=forms.SplitDateTimeWidget)

What I want to do is render each date/time part of the SplitDateTimeWidget individually in a template, just as if they were regular fields defined on the form class itself.

Something like this:

<div class="date">{{ form.when.0.label_tag }} {{ form.when.0 }}</div>
<div class="time">{{ form.when.1.label_tag }} {{ form.when.1 }}</div>

Is there a way to achieve that using only public/documented APIs?

Bonus points if I could actually write {{ }} and {{ form.when.time }} instead of {{ form.when.0 }} and {{ form.when.1 }} but I suspect that might be a lot more complicated (possibly using namedtuples somehow).

So far, I’ve only been able to achieve this result partially using a custom widget that overrides the subwidgets method:

class CustomSplitDateTimeWidget(forms.SplitDateTimeWidget):
    def subwidgets(self, *args, **kwargs):
        for multiwidget_data in super().subwidgets(*args, **kwargs):
            for subwidget in multiwidget_data['subwidgets']:
                yield subwidget

This lets me do {{ form.when.0 }} to render the field itself but I can’t render the <label> individually.

Actually, doing {{ form.when.X }} might render the label depending on the type of subwidget.
If the subwidget is a checkbox for example, it will render the both the label and the field, like so: <label ...><input ...></label>).

Thoughts? Ideas?
Thanks :sparkles:

1 Like