Skip to content Skip to sidebar Skip to footer

How To Use A Datepicker In A Modelform In Django?

I am using django 3.0 and I am trying to display a datepicker widget in my ModelForm, but I can't figure out how (all I can get is text field). I have tried looking for some soluti

Solution 1:

Although @willem-van-onsem's answer is great, there are a few alternatives that do not require additional dependencies.

A few options, in order of increasing effort:

  1. Use a SelectDateWidget instead of the default DateInput (no JavaScript required):

    classMyForm(forms.Form):
        date = forms.DateField(widget=forms.SelectDateWidget())
    
  2. Use the browser's built-in date picker, by implementing a customized widget that uses the HTML <input type="date"> element (no JavaScript required):

    classMyDateInput(forms.widgets.DateInput):
        input_type = 'date'classMyForm(forms.Form):
        date = forms.DateField(widget=MyDateInput())
    

    or, alternatively:

    classMyForm(forms.Form):
        date = forms.DateField(widget=forms.DateInput(attrs=dict(type='date')))
    
  3. Use the date picker from django.contrib.admin, as described here in detail. In short, there are a few things you would need:

    from django.contrib.admin.widgets import AdminDateWidget
    ...
    classMyForm(forms.Form):
        date = forms.DateField(widget=AdminDateWidget())
    

    then, to make this work, add the following dependencies to your template <head>:

    <linktype="text/css" href="{% static 'admin/css/widgets.css' %}" />
    <script src="{% static 'admin/js/core.js' %}"></script>
    <script src="{% url 'admin:jsi18n' %}"></script>  {# see note below #}
    {{ form.media }}  {# this adds 'calendar.js' and 'DateTimeShortcuts.js' #}   

    Now there's one catch: the admin:jsi18n url only works for users with admin access, so you may need to replace this and define an alternative path in your urls.py, e.g.:

    from django.views import i18n
    ...
    urlpatterns = [
        ...,
        path('jsi18n/', i18n.JavaScriptCatalog.as_view(), name='jsi18n'),
    ]
    

Finally, here's what the widgets look like (on firefox):

date picker examples

Personally I like the second option best. It also allows us to specify initial, minimum and maximum values (in django you can do this e.g. using the attrs argument). Here's a quick snippet to show the HTML element in action:

<inputtype="date"value="2021-09-09"min="2021-09-09">

Solution 2:

This is the expected behavior. A DateInput widget [Django-doc] is just a <input type="text"> element with an optional format parameter.

You can make use of a package, like for example django-bootstrap-datepicker-plus [pypi] , and then define a form with the DatePickerInput:

from bootstrap_datepicker_plus import DatePickerInput

classMembershipForm(ModelForm):
  class Meta:
    model = Membership
    fields = ['owner', 'start_date', 'type']
    widgets = {
        'start_date': DatePickerInput
    }

In the template you will need to render the media of the form and load the bootstrap css and javascript:

{% load bootstrap4 %}
{% bootstrap_css %}
{% bootstrap_javascript jquery='full' %}
{{ form.media }}

<form class="container" action="" method="POST">
{% csrf_token %}
{{ form|crispy }}
<button type="submit" class="btn btn-primary">Submit</button>
</form>

Post a Comment for "How To Use A Datepicker In A Modelform In Django?"