using date picker with django

This tutorial article seeks to unravel the mysteries of Django date/datetime pickers. Also, the article offers three options to explore. The first option is implementing the Django date/datetime pickers manually. The second option is implementing this datetime concept through custom widgets. Finally, you may explore the usability of a third-party Django app that supports the implementation of datetime pickers.

Introduction

The first step of this tutorial is understanding the practical implementation of the date/date-time pickers concept. You will most likely find yourself applying this concept on the front-end of your Django app. While applying this date/date-time picker concept, the key criterion lies in the syntax rules. Django needs to understand the format of the date input values keyed-in from the user interface. The input format needs to be correct for Django to translate the needed date and time values. Also, during form rendering, these date input values should be easy to reproduce as initial data.

Since we have mentioned that a date picker implementation is popular with an app’s front-end, there is an alternative for deeper integration with the back-end through custom widgets. This integration is also ideal for project re-usability as you won’t have to re-invent the wheel on any part of your project code that needs the date picker implemented.

Our understanding of date and time pickers will be complete through the exploration of three date pickers: Tempus Dominus Bootstrap 4, XDSoft DateTimePicker, and Fengyuan Chen’s Datepicker.

Tempus Dominus Bootstrap 4 date picker

You can visit the links to its Docs and Source for a thorough breakdown of its design and functional implementation.

This date picker exists as a useful JavaScript library that comfortably integrates with Bootstrap 4. The only noticeable downside to this date and time picker is its dependence on moment.js and Font Awesome. Moment.js is a JavaScript library responsible for date/time manipulation, display, validation, and parsing. It converts date/time display in a human-readable format and also per localization. Font Awesome is a needed element for display icons.

It is advisable to use this JavaScript library alongside Bootstrap 4 + jQuery as it will lessen the headaches of dealing with complicated CSS and JS concepts.

There are two approaches to installing and working with this JavaScript library, the first one is through its CDN (Content Delivery Network) and the second one is through its GitHub Releases page. The CDN link also provides an approach through which you can directly install the library on your Django project through the PIP package manager. If you opted to go with the Github Releases page code download, you should be able to trace the processed library code inside the build/ folder.

Before we dive into the Django implementation of this date picker library, consider the following static implementation of the same library code. Copy the code on your source code editor, save it as a .html file and open it with your browser application.

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>Static Example of Tempus Dominus Bootstrap 4 Implementation</title>

    <!-- Bootstrap 4 -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script>

    <!-- Font Awesome -->
    <link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">

    <!-- Moment.js -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.23.0/moment.min.js" integrity="sha256-VBLiveTKyUZMEzJd6z2mhfxIqz3ZATCuVMawPZGzIfA=" crossorigin="anonymous"></script>

    <!-- Tempus Dominus Bootstrap 4 -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tempusdominus-bootstrap-4/5.1.2/css/tempusdominus-bootstrap-4.min.css" integrity="sha256-XPTBwC3SBoWHSmKasAk01c08M6sIA5gF5+sRxqak2Qs=" crossorigin="anonymous" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/tempusdominus-bootstrap-4/5.1.2/js/tempusdominus-bootstrap-4.min.js" integrity="sha256-z0oKYg6xiLq3yJGsp/LsY9XykbweQlHl42jHv2XTBz4=" crossorigin="anonymous"></script>

  </head>
  <body>
      <div></div>
      <p style="font-size: larger; color: darkgreen; text-align: center;">Brandon Jones Teaches Tempus Dominus Bootstrap 4</p>

    <div class="input-group date" id="datetimepicker1" data-target-input="nearest">
      <input type="text" class="form-control datetimepicker-input" data-target="#datetimepicker1"/>
      <div class="input-group-append" data-target="#datetimepicker1" data-toggle="datetimepicker">
        <div class="input-group-text"><i class="fa fa-calendar"></i></div>
      </div>
    </div>

    <script>
      $(function () {
        $("#datetimepicker1").datetimepicker();
      });
    </script>
  </body>  
</html>

The following screenshot from my end depicts the resulting web browser user interface display.

static implementation of the Tempus Dominus Bootstrap 4
static implementation of the Tempus Dominus Bootstrap 4

Direct usage of Tempus Dominus Bootstrap 4 in Django

Using this library on a static HTML page was a walk in the park. The main challenge now is figuring out how to make this date picker library sync with our Django project apps. You first need to refer to the published article on setting up a complete Django project. Create a Django app with a name like date_picker, and add it to the project’s settings.py file INSTALLED_APPS section. Inside this date_picker app directory, create a forms.py file and populate it with the following data.

#forms.py file
from django import forms

class DateForm(forms.Form):
    date = forms.DateTimeField(
        input_formats=['%d/%m/%Y %H:%M'],
        widget=forms.DateTimeInput(attrs={
            'class': 'form-control datetimepicker-input',
            'data-target': '#datetimepicker1'
        })
    )

Create a templates folder inside your date_picker app directory. Create a base.html file inside the templates folder and populate it with the following code. We are just covering the basic Django project skeleton implementation and not the creation of a complete Django app.

 <!DOCTYPE html>
<html>
<head>
<title>Django Example of Tempus Dominus Bootstrap 4 Implementation</title>
<!-- Bootstrap 4 -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script>

<!-- Font Awesome -->
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">

<!-- Moment.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.23.0/moment.min.js" integrity="sha256-VBLiveTKyUZMEzJd6z2mhfxIqz3ZATCuVMawPZGzIfA=" crossorigin="anonymous"></script>

<!-- Tempus Dominus Bootstrap 4 -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tempusdominus-bootstrap-4/5.1.2/css/tempusdominus-bootstrap-4.min.css" integrity="sha256-XPTBwC3SBoWHSmKasAk01c08M6sIA5gF5+sRxqak2Qs=" crossorigin="anonymous" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/tempusdominus-bootstrap-4/5.1.2/js/tempusdominus-bootstrap-4.min.js" integrity="sha256-z0oKYg6xiLq3yJGsp/LsY9XykbweQlHl42jHv2XTBz4=" crossorigin="anonymous"></script>

</head>
<body>
    <p style="font-size: larger; color: darkgreen; text-align: center;">Brandon Jones Teaches Django Tempus Dominus Bootstrap 4</p>
	{% block content %}
	{% endblock %}
</body>
</html>

Now create a tempus_dominus.html file alongside the created base.html file. It will function as the main template file.

{% extends 'base.html' %}

{% block content %}
  <div class="input-group date" id="datetimepicker1" data-target-input="nearest">
    {{ form.date }}
    <div class="input-group-append" data-target="#datetimepicker1" data-toggle="datetimepicker">
      <div class="input-group-text"><i class="fa fa-calendar"></i></div>
    </div>
  </div>
  
  <script>
    $(function () {
      $("#datetimepicker1").datetimepicker({
        format: 'DD/MM/YYYY HH:mm',
      });
    });
  </script>
{% endblock %}

The above template file ends with a script tag. You have the freedom to position the script tag anywhere in your code template files as long as it is initialized after the jQuery script tag. The above code snippets are the missing pieces on your Django project code to directly implement Tempus Dominus Bootstrap 4.

Tempus Dominus Bootstrap 4 custom widget

Another way of implementing this JavaScript library is through a custom widget. In your project app folder, you can create a widgets.py file that will contain a widget code snippet like the following.

#widgets.py file
from django.forms import DateTimeInput

class BootstrapDateTimePickerInput(DateTimeInput):
    template_name = 'widgets/bootstrap_datetimepicker.html'

    def get_context(self, name, value, attrs):
        datetimepicker_id = 'datetimepicker_{name}'.format(name=name)
        if attrs is None:
            attrs = dict()
        attrs['data-target'] = '#{id}'.format(id=datetimepicker_id)
        attrs['class'] = 'form-control datetimepicker-input'
        context = super().get_context(name, value, attrs)
        context['widget']['datetimepicker_id'] = datetimepicker_id
        return context

As you can see from the above code implementation, a unique ID called datetimerpicker_id is generated making it inclusive in the widget context. This widget code is the back-end implementation. To use it on the front-end, we will need to create a Widget HTML snippet. The following HTML template code will suffice. Create a widgets folder alongside the templates folder inside your create Django app’s directory (date_picker).

widgets/bootstrap_datetimepicker.html

<div class="input-group date" id="{{ widget.datetimepicker_id }}" data-target-input="nearest">
    {% include "django/forms/widgets/input.html" %}
    <div class="input-group-append" data-target="#{{ widget.datetimepicker_id }}" data-toggle="datetimepicker">
      <div class="input-group-text"><i class="fa fa-calendar"></i></div>
    </div>
  </div>
  
  <script>
    $(function () {
      $("#{{ widget.datetimepicker_id }}").datetimepicker({
        format: 'DD/MM/YYYY HH:mm',
      });
    });
  </script>

The include file path django/forms/widgets/input.html is Django’s built-in HTML template file. Since our implementation is for custom widget, we will be using a different forms.py file. Your Django app’s forms.py file should now have the following code data.

from .widgets import BootstrapDateTimePickerInput

class DateForm(forms.Form):
    date = forms.DateTimeField(
        input_formats=['%d/%m/%Y %H:%M'], 
        widget=BootstrapDateTimePickerInput()
    )

To use the date picker field, we simply need to render it on an active template using the following one line code.

{{ form.date }}

The use of this widget approach gives you some flexibility in your code. A good example is an instance where you are dealing with several date fields. To render such a form, you will only need a code snippet like the following.

<form method="post">
  {% csrf_token %}
   {{ form.as_p }}
  <input type="submit" value="Submit">
</form>     

XDSoft DateTimePicker

You can visit the links to its Docs and Source for a thorough breakdown of its design and functional implementation.

The uniqueness of this date picker is in its versatility. Its functional implementation is independent of both Bootstrap and moment.js but implementing it alongside Bootstrap is good for an appealing web display. Working with it is easy and direct. The GitHub releases page hosts its downloadable source. The following static example should give you an idea implementation of this date picker before we look at the useful code snippets you need to make it work with your Django project apps.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <title>XDSoft DateTimePicker Static Implementation</title>

  <!-- jQuery -->
  <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>

  <!-- XDSoft DateTimePicker -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-datetimepicker/2.5.20/jquery.datetimepicker.min.css" integrity="sha256-DOS9W6NR+NFe1fUhEE0PGKY/fubbUCnOfTje2JMDw3Y=" crossorigin="anonymous" />
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-datetimepicker/2.5.20/jquery.datetimepicker.full.min.js" integrity="sha256-FEqEelWI3WouFOo2VWP/uJfs1y8KJ++FLh2Lbqc8SJk=" crossorigin="anonymous"></script>
</head>
<body>
    <div></div>
    <p style="font-size: larger; color: darkgreen; text-align: center;">Brandon Jones Teaches XDSoft DateTimePicker Static Implementation</p>
     <div style="text-align: center;">  
    <input id="datetimepicker" type="text">
     </div>
  <script>
    $(function () {
      $("#datetimepicker").datetimepicker();
    });
  </script>

</body>
</html>

The resulting web browser view is as follows:

XDSoft DateTimePicker static implementation on a HTML template
XDSoft DateTimePicker static implementation on a HTML template

XDSoft DateTimePicker direct usage

To integrate this date picker with your Django project apps, your forms.py file will look like the following.

from django import forms

class DateForm(forms.Form):
    date = forms.DateTimeField(input_formats=['%d/%m/%Y %H:%M'])

As you can see the Django form is in its simplest state with a default widget that is familiar to us. The Django HTML template that goes hand-in-hand with this form will look like the following code snippet. We can give it a name like xdsoft.html.

{{ form.date }}

<script>
  $(function () {
    $("#id_date").datetimepicker({
      format: 'd/m/Y H:i',
    });
  });
</script>

The id_date argument in the script function is a Django-generated default ID. It is for the id_ + name form fields.

XDSoft DateTimePicker custom widget

Your widgets.py file will have the following few lines of code.

from django.forms import DateTimeInput

class XDSoftDateTimePickerInput(DateTimeInput):
    template_name = 'widgets/xdsoft_datetimepicker.html'

The associated widgets HTML template file code will look like the following.

widgets/xdsoft_datetimepicker.html

{% include "django/forms/widgets/input.html" %}

<script>
  $(function () {
    $("input[name='{{ widget.name }}']").datetimepicker({
      format: 'd/m/Y H:i',
    });
  });
</script>

The first line of code in this widget template points to an input.html file that is built-in in Django. As you might have noted, this implementation is somewhat generic. The initialization of the form field component for the date picker is by name and not id. The flexibility of this implementation is precautious of circumstances where a user might end up editing or changing the id prefix. The forms.py file that syncs with the usage of this widget template will look like the following.

from django import forms
from .widgets import XDSoftDateTimePickerInput

class DateForm(forms.Form):
    date = forms.DateTimeField(
        input_formats=['%d/%m/%Y %H:%M'], 
        widget=XDSoftDateTimePickerInput()
    )

The main Django project app template file for the final implementation of the XDSoft DateTimePicker custom widget will constitute the following one line code.

{{ form.date }}  

Fengyuan Chen’s Datepicker

You can visit the links to its Docs and Source for a thorough breakdown of its design and functional implementation.

The only way to describe this last candidate on our Django date pickers list is in the way it parades its minimalist and beautifully implemented functional design. The main drawback of Fengyuan Chen’s DatePicker is its exclusion of time support in its functionality. But if your Django project apps only need to deal with dates, then this date picker’s functional delivery will never disappoint. To install and use it, you have the option of downloading its sources from the GitHub releases page or you can take the CDN approach. Accessing this date picker from the GitHub releases page does not allocate its processed/compiled JavaScript files, but the CDN approach optionally allows you to download these files and store them on a local machine if needed.

The following is the code snippet for its static implementation. Copy it and save it as a .html file and open it with a browser application.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <title>Fengyuan Chen's Datepicker Static Implementation</title>
  <style>body {font-family: Arial, sans-serif;}</style>
  
  <!-- jQuery -->
  <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>

  <!-- Fengyuan Chen's Datepicker -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/datepicker/0.6.5/datepicker.min.css" integrity="sha256-b88RdwbRJEzRx95nCuuva+hO5ExvXXnpX+78h8DjyOE=" crossorigin="anonymous" />
  <script src="https://cdnjs.cloudflare.com/ajax/libs/datepicker/0.6.5/datepicker.min.js" integrity="sha256-/7FLTdzP6CfC1VBAj/rsp3Rinuuu9leMRGd354hvk0k=" crossorigin="anonymous"></script>
</head>
<body>
    <div></div>
    <p style="font-size: larger; color: darkgreen; text-align: center;">Brandon Jones Teaches Fengyuan Chen's Datepicker Static Implementation</p>  
    <div style="text-align: center;">
  <input id="datepicker">
    </div>>
  <script>
    $(function () {
      $("#datepicker").datepicker();
    });
  </script>

</body>
</html>

The resultant browser view of the above HTML enclosed template code should be similar to the following screenshot.

Fengyuan Chen’s Datepicker static implementation
Fengyuan Chen’s Datepicker static implementation

Fengyuan Chen’s Datepicker direct usage

Since this date picker does not support a time field, our forms.py file will now consider the usage of DateField and not DateTimeField.

from django import forms

class DateForm(forms.Form):
    date = forms.DateField(input_formats=['%d/%m/%Y'])

The HTML template file that complements this forms.py file will look like the following. We can name it fengyuan.html.

{{ form.date }}

<script>
  $(function () {
    $("#id_date").datepicker({
      format:'dd/mm/yyyy',
    });
  });
</script>

Fengyuan Chen’s Datepicker custom widget

For the custom widgets approach, the related widgets.py file will have a code segment similar to the following.

from django.forms import DateInput

class FengyuanChenDatePickerInput(DateInput):
    template_name = 'widgets/fengyuanchen_datepicker.html'

The named HTML template file on this widgets.py file that constitutes the widgets template should look like the following file.

widgets/fengyuanchen_datepicker.html

The first statement of this file, like in the custom widgets of the other date pickers, points to a built-in Django HTML template file. The usage of this custom widget approach requires that our app’s forms.py file is populated with the following code snippet.

from django import forms
from .widgets import FengyuanChenDatePickerInput

class DateForm(forms.Form):
    date = forms.DateTimeField(
        input_formats=['%d/%m/%Y'], 
        widget=FengyuanChenDatePickerInput()
    )

As for the Django app’s main HTML template file, you will need to populate it with the following one-line code as part of its code data.

{{ form.date }}  

Final note

As you might have noticed, working with the above three date pickers portray a similar implementation convention. We honestly hope that this date pickers tutorial article’s insights will provide a breakthrough for your projects that need date and time pickers. This article prioritized a warm introduction to date pickers. If you find this introduction not digestible enough, the provided documentation links in this article for the date pickers we have discussed are enough to answer any puzzling questions you might have. Good luck as you make and pick the perfect date.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *