What's the cleanest, simplest-to-get running datepicker in Django?
Asked Answered
W

14

83

I love the Thauber Schedule datepicker, but it's a datetime picker and I can't get it to just do dates. Any recommendations for nice looking datepickers that come with instructions on how to integrate with a Django date form field?

Wescott answered 29/7, 2010 at 21:28 Comment(2)
If you're comfortable with the Django Admin's date widget, you can include that in your app. The advantage is no external dependencies. Someone posted a how-to on the django-users group some time ago: - Using Admin DateTime Picker in your FormAfroamerican
If I ask questions which belong to softwarerecommendations, then they get down-voted or closed. You are lucky :-)Dorsal
E
31

You can also simply use Jquery in your templates. The jquery DateTime Picker allows each customization.

http://jqueryui.com/demos/datepicker/

Emeric answered 30/7, 2010 at 2:0 Comment(4)
Thanks. I'd never dug into JQuery, but a few hours of puttering around it got me exactly where I wanted to be.Wescott
Np, good luck with your project. But remember, Jquery is simply javascript on the client side. It is thus possible for someone to post data to your form class with incorrect or malicious data, thus validate everything and put the view actions in a try/except clause.Emeric
For validation of data, use Django forms (docs.djangoproject.com/en/dev/topics/forms)Philology
Is there any way to change the language of the date picker?Disburden
H
114

Following is what I do, no external dependencies at all.:

models.py:

from django.db import models


class Promise(models):
    title = models.CharField(max_length=300)
    description = models.TextField(blank=True)
    made_on = models.DateField()

forms.py:

from django import forms
from django.forms import ModelForm

from .models import Promise


class DateInput(forms.DateInput):
    input_type = 'date'


class PromiseForm(ModelForm):

    class Meta:
        model = Promise
        fields = ['title', 'description', 'made_on']
        widgets = {
            'made_on': DateInput(),
        }

my view:

class PromiseCreateView(CreateView):
    model = Promise
    form_class = PromiseForm

And my template:

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

The date picker looks like this:

enter image description here

Homograph answered 13/3, 2016 at 9:51 Comment(13)
I get Enter a valid date/time. error with "datetime-local". Maybe the validator must be adapted as well?Extinctive
@Extinctive can you show the code and also full error stack trace?Homograph
Also, in HTML form, whats the input type?Homograph
Comments here are not appropriate for debugging. The code is on Github. It was the "deadline" field in "issues/models.py", if you really want to dig into this.Extinctive
Where does CreateView come from?Polish
CreateView comes from Django itself. It's a generic class based view - linkHomograph
Its works for me without any external dependencies great job.Marrowfat
Works on FF but not IESwink
This solution is the simplest and straightforward and it is currently working on my Django 2.2.8 app.Mindexpanding
This solution is great for create views, but overrides the date pulled from the database with "dd/mm/yyyy" when using an update view and the date needs to be input again before the form is able to submit, not sure how this is happening, as inspecting the element in firefox, shows that the date is very much there just not being displayed. Has anyone found a solution to this problem?Vanquish
@Vanquish I beleive this is because Django will "localize" your datetime before putting it in the field (it's not aware we've changed the input type), and in doing so move away from a formatting that would work. You might be able to solve this by adding localize=False to your DateField (docs.djangoproject.com/fr/2.2/topics/i18n/formatting)Justinajustine
Thanks for giving a solution without external dependency. To add to the answer, this can also be done without creating a dedicated class. widgets = {'made_on': forms.DateInput(attrs={'type': 'date'})}Piacular
Does anybody know how to use this on function-based views?Jujutsu
J
78

Django's TextInput widget (and all of its subclasses) support specifying a type attribute to set the type of form.

You can use this to set the input type to date (W3C specification), for example in the following way :

date = fields.DateField(widget=forms.widgets.DateInput(attrs={'type': 'date'}))

To apply this on a forms.ModelForm:

class MyModelForm(forms.ModelForm):
    class Meta:
        model = MyModel
        fields = ['my_field', 'date']
        widgets = {
            'date': forms.widgets.DateInput(attrs={'type': 'date'})
        }
Justinajustine answered 6/8, 2016 at 12:12 Comment(5)
This works really nicely... if you're clients will only use the Chrome browser. The HTML attribute needed to implement this isn't currently supported in Safari or Firefox.Cree
Here is the current browser support.Hunyadi
To set initial value put the parameter initial with this format DateInput(initial=datetime.now().strftime("%Y-%m-%d"), widget=forms.widgets.DateInput(attrs={'type': 'date'}))Mahmoud
in Django3.1 following was needed: import datetime and date = forms.DateField(initial=datetime.date.today, widget=forms.widgets.DateInput(attrs={'type': 'date'}))Theressa
@ChristophLösch this solution doesn't work for me in Django 3.2, unfortunately :-/Mulish
E
31

You can also simply use Jquery in your templates. The jquery DateTime Picker allows each customization.

http://jqueryui.com/demos/datepicker/

Emeric answered 30/7, 2010 at 2:0 Comment(4)
Thanks. I'd never dug into JQuery, but a few hours of puttering around it got me exactly where I wanted to be.Wescott
Np, good luck with your project. But remember, Jquery is simply javascript on the client side. It is thus possible for someone to post data to your form class with incorrect or malicious data, thus validate everything and put the view actions in a try/except clause.Emeric
For validation of data, use Django forms (docs.djangoproject.com/en/dev/topics/forms)Philology
Is there any way to change the language of the date picker?Disburden
A
16

When it comes to date-pickers my choice is Bootstrap Datepicker. You can implement it in your django app by using django-bootstrap-datepicker-plus which works both on newer and older DJango versions. I maintain the repository and tested it working in DJango version 1.8, 1.10, 1.11 and 2.0.4.

bootstrap datepicker

The setup is quite easy. You just install it.

  pip install django-bootstrap-datepicker-plus

Import the widget in your forms.py file

    from bootstrap_datepicker_plus import DatePickerInput

Add the widget to your date field

    class ToDoForm(forms.Form):
        date = forms.DateField(
            widget=DatePickerInput(
                options={
                    "format": "mm/dd/yyyy",
                    "autoclose": True
                }
            )
        )

Detailed instructions are available on the django-bootstrap-datepicker-plus Github Page.

Disclaimer: This widget package is now owned and maintained by me. For any issues with it feel free to open issues on the Github Page.

Annieannihilate answered 2/3, 2018 at 7:57 Comment(3)
Thanks for this Mumin, is it possible to extend this package to be used as a date slider as opposed to a date picker?Submiss
@Submiss can you give me an example?Annieannihilate
of course - something like this would be awesome.Submiss
G
14

avi's solution can also be done without using an additional django input class:

class PromiseForm(ModelForm):

    class Meta:
        model = Promise
        fields = ['title', 'description', 'made_on']
        widgets = {
            'made_on': DateInput(attrs={'type': 'date'}),
        }
Goraud answered 30/1, 2017 at 18:18 Comment(1)
You miss the import: from django.forms.widgets import DateInputBacktrack
B
6

Being newer to coding, I used this example due to it's ease.

<form method="POST">{% csrf_token %}        
    <p>Start date<input type = 'date'  name='start_date' ></p>
    <p>End date<input type = 'date'  name='end_date' ></p>
    <button type="submit">Submit</button>
</form>
Banta answered 7/8, 2015 at 23:25 Comment(4)
That's not a datepicker. Though some browsers may elect to display a datepicker, it's definitely not the norm.Pinon
@spectras: In fact, it is norm since HTML5, see here or here.Mullin
It is norm, as in "browser must know this has a date inside". Norm, however, does not say how it must be shown. Internet Explorer, Firefox and Safari will all display them as regular text boxes, which is perfectly fine with the norm… but not what the OP wants.Pinon
At the time your comment was most likely correct, however almost all browsers have adopted <input type="date"> support at the very least (see caniuse.com/input-datetime)Norinenorita
C
3

Here's an ultra simple way using just html5 and django:

forms.py

class DateInput(forms.DateInput):
    input_type = 'date'

class DateForm(forms.Form):
    start_date = forms.DateField(widget=DateInput)
    end_date = forms.DateField(widget=DateInput)

Views.py

def search_dates(request, pk=''):
    if request.method == "GET": # select dates in calendar
        form = DateForm()
        return render(request, 'search.html', {"form":form})
    if request.method == "POST": # create cart from selected dates
        form = DateForm(request.POST)
        if form.is_valid():
            start = form.cleaned_data['start_date']
            end = form.cleaned_data['end_date']
            start_date = datetime.strftime(start, "%Y-%m-%d")
            end_date = datetime.strftime(end, "%Y-%m-%d")
            print(start_date)
            print(end_date)
    return render(request, 'search.html', {"form":form})

Template

 <form  method="post">
        {% csrf_token %}
        {{ form.as_table }}
        <p style="text-align: center"><input type="submit" value="Search"></p>
 </form>
Choochoo answered 30/7, 2021 at 14:37 Comment(0)
J
2

I found this quite smooth for a DateTimeField friendly option https://github.com/asaglimbeni/django-datetime-widget

Needed to include bootstrap-timepicker css file from malot and it worked quite neatly.

Jilly answered 6/6, 2013 at 10:2 Comment(1)
How would I implement this into a Django forms.Form element instead of referencing a model?Stalingrad
P
2

This is what worked for me . I am using Django 1.11 with bootstrap 3.3 .

Form.py

from django.contrib.admin.widgets import AdminDateWidget

class AddInterview(forms.ModelForm):
    class Meta:
        model = models.Interview
        fields = ['candidate', 'date', 'position', 'question_set']

    date = forms.DateField(widget=AdminDateWidget())

Template:

    <form method="post">
        <div class="form-group">
            {% csrf_token %}
            {{ form.media }}
            {{ form.as_p }}
            <p>Note: Date format is yyyy-mm-dd</p>

        </div>

CSS: (In same above html template file)

<link rel="stylesheet" type="text/css" href="{% static 'admin/css/forms.css' %}"/>
<link rel="stylesheet" type="text/css" href="{% static 'admin/css/widgets.css' %}"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" >

JS:(In same above html template file)

<script type="text/javascript" src="/admin/jsi18n/"></script>
<script type="text/javascript" src="{% static 'admin/js/core.js' %}"></script>
<script type="text/javascript" src="{% static 'admin/js/admin/RelatedObjectLookups.js' %}"></script>
<script type="text/javascript" src="{% static 'admin/js/vendor/jquery/jquery.min.js' %}"></script>
<script type="text/javascript" src="{% static 'admin/js/jquery.init.js' %}"></script>
<script type="text/javascript" src="{% static 'admin/js/actions.min.js' %}"></script>
<script type="text/javascript" src="{% static 'admin/js/calendar.js' %}"></script>
<script type="text/javascript" src="{% static 'admin/js/admin/DateTimeShortcuts.js' %}"></script>
Picardi answered 8/10, 2018 at 12:25 Comment(0)
P
2

Here is my favorite implementation that works directly from CreateView.

from django.views.generic import CreateView
from django.contrib.admin.widgets import AdminDateWidget
from .models import MyModel

class MyModelCreateView(CreateView):
    template_name = 'form.html'
    model = MyModel
    fields = ['date_field', ...]

    def get_form(self, form_class=None):
        form = super(MyModelCreateView, self).get_form(form_class)
        form.fields['date_field'].widget = AdminDateWidget(attrs={'type': 'date'})
        return form

The only thing that could be easier is to have this be the default behavior for Generic CBVs!

Persinger answered 27/6, 2022 at 20:17 Comment(0)
D
1

Use datetime-local as type for the input.Its not very fancy looking.But will do the Job

Hope this helps.enter image description here

Decalescence answered 18/6, 2016 at 9:23 Comment(1)
Did you use Django's DateTimeInput for this implementation? How did you set the format? That's the biggest problem I'm having right now. <#61620589>Lilllie
G
1

This is what i do to get datepicker in django forms.

install bootstrap_datepicker_plus by pip command.

pip install django-bootstrap_datepicker_plus

forms.py

from .models import Hello
from django import forms
from bootstrap_datepicker_plus import DatePickerInput

class CreateForm(forms.ModelForm):
    class Meta:
        model = Hello
        fields =[            
            "Date",
        ]

    widgets = {
        'Date': DatePickerInput(),
    }

settings.py

INSTALLED_APPS = [
    'bootstrap_datepicker_plus',
]
Gaona answered 23/1, 2019 at 10:36 Comment(0)
V
0

I have been struggling with a similar problem and I found the following solution pleasing, using floppy forms:

This works really well and is relatively easy to implement, hope someone will find it help full. Good luck.

Verwoerd answered 11/12, 2014 at 10:19 Comment(0)
J
0

Just adding this line of code to my template html, solved my problem:

<div class="mb-3">
<label for="exampleFormControlInput1" class="form-label">Email address</label>
<input type="date" class="form-control" id="exampleFormControlInput1" placeholder="[email protected]">
</div>

enter image description here

[source]

Jujutsu answered 15/9, 2022 at 12:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.