In Python, if you have a Django form form with a field named foo, you can’t use the attribute access syntax form.foo to access the field; instead you must use form.fields['foo'].
But in a template you can — and normally do — use {{ form.foo }} to render the field, using the normal attribute access syntax that works for any object in templates.
Why/how does the template {{ form.foo }} work when Python form.foo doesn’t? Is it a bit of special handing that Django does when rendering templates? Or am I just misunderstanding something simple?
EDIT: I know that Django’s template language isn’t Python and there are many differences from Python. I am just curious why the {{ form.foo }} syntax works and/or how it’s implemented in the case of forms. After all, normally the template {{ object.attribute }} syntax DOES work analogously to the Python object.attribute syntax, but in the case of a form it seems to be handled as a special case.
Django’s templating language, as Kerrek SB mentions, isn’t Python, even if it sometimes looks like it.
{{ object.attribute }}does appear to mimic Python’s attribute lookup, but it is just a special case of{{ a.b }}in the template language.When you use
{{ a.b }}in a template, the interpreter will first look upain the current context. Once it has that, it will try the following things to resolvea.b:a["b"]a.ba.b()(in the case wherebis a method ofa)a[b](in the case wherebis a number)For forms, specifically,
a["b"]is what is used. You can refer to a field"foo"asform.fields["foo"]or asform["foo"]. That bit of magic comes from the form class, though, and not the template language.