Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Datetime values in Django forms (initial and submitted has different format thought)

For some reason I use a custom HTML-code for displaying the form. My form's input get the initial value (date), and shows the same form after submittion.

But after submit, input has no previously selected value (just empty).

I use {{ Form.Fileld.value|date:"Y-m-d" }} in the temlate to get initial and submitted values.

It seems that initial and submitted values are in different formats: "datetime" for initial values and "string" after submit.

Here is my simple test:

Form

class ShowStartEndDateForm(forms.Form):
    start_date = forms.DateField(initial=date.today().replace(day=1), 
        label="Start", 
        widget=forms.DateInput(format='%Y-%m-%d'), 
        input_formats=['%Y-%m-%d'])
    ...

View

if request.method == 'POST':
    form_date = ShowStartEndDateForm(request.POST)

    if form_date.is_valid():
        form_was_submitted = True
        cd = form_date.cleaned_data
        operator = cd['operators']

        days=[]
        for day in range(0,(cd['end_date']-cd['start_date']).days+1):
            days.append(cd['start_date']+relativedelta(days=+day))

else:
    form_date = ShowStartEndDateForm()

return render_to_response('epay.html', locals(),
    context_instance=RequestContext(request))

Template

<!- HTML FORM here 
|classname is my custom template filter.
-->
Date1: {{ form_date.start_date.value|date:"Y-m-d" }} \
({{ form_date.start_date.value|classname }})
Date2: {{ form_date.start_date.value }}

First call in browser:

Date1: 2013-10-01 (date)
Date2: 1 October 2013

After form submit:

Date1: (unicode)
Date2: 2013-10-01

What am I doing wrong? What is the proper way to access form's field initial and submitted values?

Thnak you.

like image 562
Lufa Avatar asked Oct 09 '13 14:10

Lufa


1 Answers

You're question is a bit confusing (you should add some more of your actual code), but I know from experience that when mixing between formats, its a good convention to just do it all in one place. So instead of specifying the format on the client side like you do, specify it all on the form itself and then everything would (should) be in-sync.

class ShowStartEndDateForm(forms.Form):
    start_date = forms.DateField(initial=date.today().replace(day=1), 
                                 label="Start", 
                                 widget=DateInput(format='%Y-%m-%d'), 
                                 input_formats=['%Y-%m-%d'])

i.e. you tell the the DateInput widget what form to take and you tell input_formats (for the field itself) what formats to expect (you can add more than one). Also, if you are using some sort of datepicker you of course need to make sure it is also using the right format.

Edit

I replicated this and everything was fine:

In [1]: from test.forms import *

In [2]: f = ShowStartEndDateForm()

In [3]: print f
<tr>
    <th><label for="id_start_date">Start:</label></th>
    <td><input id="id_start_date" name="start_date" type="text" value="2013-10-01" /></td>
</tr>

(of course I changed the indentation here so you could see it more clearly)

like image 98
yuvi Avatar answered Sep 22 '22 07:09

yuvi