Is the initial value of a form field available in the template?

1,120 views
Skip to first unread message

ChrisK

unread,
Nov 26, 2008, 2:14:04 PM11/26/08
to Django users
I'm doing a custom template (probably stupid), and using initial
values. Here's a precis:

template has

<form action="/map/fences/newFence/" method="POST">
{{form.url.field.initial}}
{{form.auth_id}} {{form.media_id}} {{form.fence_id}}
<p><label for="id_teaser">Reminder String:</label>
<input id="id_teaser" type="text" name="teaser" maxlength="40" /></
p>

form type looks like

class editFenceForm(forms.Form):
teaser = forms.CharField(max_length=40)
auth_id = forms.CharField(widget=forms.HiddenInput)
media_id = forms.IntegerField(widget=forms.HiddenInput)
fence_id = forms.IntegerField(widget=forms.HiddenInput)

invocation looks like

form = editFenceForm(initial={
'auth_id' : auth_id, 'fence_id': fence_id, 'media_id':
m_id,
'teaser': m.teaser, })

output html looks like

<form action="/map/fences/newFence/" method="POST">
None
<input type="hidden" name="auth_id" value="ckantarj" id="id_auth_id" /
> <input type="hidden" name="media_id" value="13" id="id_media_id" />
<input type="hidden" name="fence_id" value="27" id="id_fence_id" />
<p><label for="id_teaser">Reminder String:</label>
<input id="id_teaser" type="text" name="teaser" maxlength="40" /></
p>

I'm really not expecting "None" there. If I just use {{form.as_p}},
the values are filled in correctly.

What am I missing?

Thanks,
chris

Rajesh Dhawan

unread,
Nov 26, 2008, 2:32:17 PM11/26/08
to Django users
Obviously, {{form.url.field.initial}} is causing it. The question is,
do you have a field called url in your form. Your Form class
definition above does not show such a field nor are you trying to set
an initial value for it in the form instantiation. Perhaps you want to
paste your test code again?

-Rajesh D.

ChrisK

unread,
Nov 26, 2008, 3:19:10 PM11/26/08
to Django users
Sorry, I cut down my example poorly.

template has

<form action="/map/fences/newFence/" method="POST">
{{form.teaser.field.initial}}
{{form.auth_id}} {{form.fence_id}}
<p><label for="id_teaser">Reminder String:</label>
<input id="id_teaser" type="text" name="teaser" maxlength="40" /
></
p>

invocation looks like

print m.teaser
form = editFenceForm(initial={
'auth_id' : auth_id, 'fence_id': fence_id,
'teaser': m.teaser, })

and, indeed, the print statement produces a value

resulting HTML looks like

<form action="/map/fences/editFence/" method="POST">

<input type="hidden" name="auth_id" value="ckantarj" id="id_auth_id" /
> <input type="hidden" name="fence_id" value="5" id="id_fence_id" />

Malcolm Tredinnick

unread,
Nov 26, 2008, 9:00:04 PM11/26/08
to django...@googlegroups.com
I think you really need to explain what the real problem is that you're
trying to solve, because you're asking a question that is too specific.

On Wed, 2008-11-26 at 12:19 -0800, ChrisK wrote:
> Sorry, I cut down my example poorly.
>
> template has
>
> <form action="/map/fences/newFence/" method="POST">
> {{form.teaser.field.initial}}
> {{form.auth_id}} {{form.fence_id}}
> <p><label for="id_teaser">Reminder String:</label>
> <input id="id_teaser" type="text" name="teaser" maxlength="40" /
> ></
> p>

The answer to your question as to whether this is correct syntax is
"yes, it is". However, I guess from the fact that you asked the
question, that what you're really asking is how to get the initial value
that the form will assign to the field. Since initial data can come from
either the form or the field, the way you are accessing it above is too
specific (in this case, the field class itself doesn't have initial
data, but the form might well have some initial data for that field).

If you look in django/forms/forms.py in the BoundField.as_widget()
method, you'll see how Django works out the value for a form widget.
It's a combination of the forms "data" value for the field, form initial
data and field initial data. Which also hints that it's almost never
going to be correct to force the use of "initial" data at the template
level, since if there's form-supplied "data" data, that should override
the "initial" data value. At the template level, attemptign to
differentiate between a value that was an initial default and a value
that was supplied by a previous post to the form is not really
appropriate. Even if you could do so, it would be exploiting a leaky
abstraction. At the form display level, you simply shouldn't care about
that difference.

Again, it comes to down to "what is the real problem you are trying to
solve?"

At the templ

Regards,
Malcolm


ChrisK

unread,
Dec 1, 2008, 1:45:48 PM12/1/08
to Django users

> I think you really need to explain what the real problem is that you're
> trying to solve, because you're asking a question that is too specific.

Fair enough. It's been several days, so I had to dredge a bit to
remember :-)

I think the basic issue is that there are some fields in the object
that I'd like to display but not have editable, and it's not at all
clear to me how to make that happen in the form processor. The values
are dynamic, so they can't be in the template.

I'm happy not to replicate the logic inside BoundField.as_widget(), if
there's some way that the "correct" value is exposed to the
template...

DavidA

unread,
Dec 1, 2008, 4:53:27 PM12/1/08
to Django users
> I think the basic issue is that there are some fields in the object
> that I'd like to display but not have editable, and it's not at all
> clear to me how to make that happen in the form processor. The values
> are dynamic, so they can't be in the template.

I often have this need so I created a custom widget where I just set
the readonly attribute on a TextInput widget:

class LabelWidget(forms.TextInput):
def __init__(self, *args, **kwargs):
attrs = kwargs.get('attrs', {})
attrs['readonly'] = True
if 'class' in attrs:
attrs['class'] = attrs['class'] + ' label'
else:
attrs['class'] = 'label'
super(LabelWidget, self).__init__(*args, **kwargs)

Then I use it in forms like this:

class AccountForm(forms.Form):
name = forms.CharField(widget=LabelWidget)
business = forms.CharField(widget=LabelWidget(attrs={'size': 5}))
...

I set/add 'label' to the CSS class so I can style these differently. I
used a custom widget over explicit "form.initial['field']" syntax in
my template so I could let the form lay itself out automatically
treating all fields the same way.

-Dave

ChrisK

unread,
Dec 1, 2008, 8:44:47 PM12/1/08
to Django users


> I often have this need so I created a custom widget where I just set
> the readonly attribute on a TextInput widget:
>
> class LabelWidget(forms.TextInput):

Thanks but ... it seems that form.as_p doesn't understand how to
display this!

ChrisK

unread,
Dec 1, 2008, 8:46:41 PM12/1/08
to Django users
Ooops. Never mind.

Sarang

unread,
Apr 21, 2011, 3:45:38 PM4/21/11
to django...@googlegroups.com
This works:

form.initial.fieldname
Reply all
Reply to author
Forward
0 new messages