Dynamic Initial Values in Django Forms

I recently had cause to create a form with two date time fields which had the default values of midnight seven days ago, and midnight this morning. Initially I thought this would be easy and created the following form.

from datetime import datetime, date, timedelta

class MyForm(forms.Form):
    date_from = forms.DateTimeField(label="From",
                               initial=(date.today() - timedelta(days=7)))
    date_to = forms.DateTimeField(label="To", initial=date.today())

This works fine except that when a process has been running across more than one day the initial values are no longer correct as they refer to the day the process started. Fortunately it appears that there is an undocumented feature where the initial value can be a function rather than an absolute value. This function is called each time the unbound form is displayed, so they are always correct.

Wrapping the code to create the value in a lambda works great here, as does passing a reference to a function.

from datetime import datetime, date, timedelta

class MyForm(forms.Form):
    date_from = forms.DateTimeField(label="From",
                 initial=lambda: (date.today() - timedelta(days=7)))
    date_to = forms.DateTimeField(label="To", initial=date.today)
Want to read more like this? Follow me with your favourite feed reader (e.g. Feedly), or subscribe to my SubStack newsletter.

Comments

Why not just:

f = MyForm(initial={'date_from': (date.today() - timedelta(days=7))}

Tomasz

22 Jul 2009

That would work, but to me it seems cleaner to have the defaults specified in the form rather than where you use it. What if you use the form in more than one place?

Andrew Wilkinson

06 Aug 2009

wolla initial it is easy on ear thanks :D

overcomes

23 Nov 2009