datepicker for forms.DateInput missing?

Hello again,
my first real django project is getting bigger and better every day and it is really fun.
Meanwhile I got my first customized form (using manually created CSS) running. Creating a new data set and editing an existing one works like a charm. Perfect so far.
But for the datefields I am missing the datepicker.
It turns out the widget form.DateInput renders to type="text" (yes, it is specified like this in the documentation) but to get the datepicker running in the browser, there should rather be type="date". I tried something but it is not clear to me how to do it in the best way.

My model looks like this:

class Quote(models.Model):
   ...
    dateinitiated = models.DateField(verbose_name="Quote initiated - Date", null=True, blank=True)
   ...

In forms.py I have this:

class QuoteForm(forms.ModelForm):
    class Meta:
        model = Quote
        fields = "__all__"

    widgets = {
        ...
        "dateinitiated": forms.DateInput(format="%Y-%m-%d",
                                         attrs={"type": "date"}),
        ...
    }

With this, no datepicker appears in the browser.
The html-page shows this:

<tr>
    <th class="xform"><label for="id_dateinitiated">Quote initiated - Date:</label></th>
    <td class="xform"><input type="text" name="dateinitiated" id="id_dateinitiated"></td>
</tr> 

Using this rendered text to change the template testwise partly and manually for this field like so (look: there is the type=“date” thing !):

<tr>
    <th class="xform">MyDate</th>
    <td class="xform"><input type="date" name="dateinitiated" id="id_dateinitiated"></td>
</tr> 

…makes the datepicker showing up in the browser!


Perfect (almost - I still strugggle with the format, but that’s ok for now).
What’s the trick to get the datepicker alive (hopefully without the need of changing my form definition entirely)?
Thank you for reading and thinking about a solution!
Mirko

Oops, I forgot the template(s):…
This is how it works more less well but not showing the datepicker for the date fields:

...
<form method="POST">
    {% csrf_token %}
    <table class="xform">
...
        <tr>
            <th class="xform">{{ form.dateinitiated.label_tag }}</th>
            <td class="xform">{{ form.dateinitiated }}</td>
        </tr>                       
...
    </table>
    {% if user.is_authenticated %}
        <input class="xformbtn" type="submit" value="Submit">
    {% endif %}
</form>
...

And this is how the datepicker appears:

<form method="POST">
    {% csrf_token %}
    <table class="xform">
...
      <tr>
          <th class="xform">MyDate</th>
          <td class="xform"><input type="date" name="dateinitiated" id="id_dateinitiated" format="%Y-%m-%d"></td>
      </tr>                      
...
    </table>
    {% if user.is_authenticated %}
        <input class="xformbtn" type="submit" value="Submit">
    {% endif %}
</form>

If this is an accurate copy of your code, you don’t have the widgets definition properly indented. It needs to be part of the Meta class definition.

I remember Django’s built-in widget is using HTML’s native input.

It indeed work but also have some drawbacks, for example, different styles in different browser, some minor issue on mobile devices.

So you can keep using Django’s widget, or you can take a look at some solution such as https://flatpickr.js.org/

You can build a custom widget using it and then use it in Django form like this

date_field = forms.DateField(initial=timezone.now, widget=CustomDateWidget)

If you want to see a real demo, here is the link: https://app.saashammer.com/lookbook/inspect/datetime_component/pick_datetime/

1 Like

Thank you very much for the quick answers!
Ken, yes - the wrong indentation was the issue, this is fixed now. I think I would not have figured that out without your hint. Now I also have to fix a few other layout things but that is sth that I understand, why it happened. I am pretty sure your hint saved me many, many hours of desperate search. Appreciate once more your help!
Michael, thank you for the hints as well, I will have a look at it soon. On the other hand I am deliberately trying to use what django provides itself in first place in order to keep it “simple”.
Regards,
Mirko