What's the difference between using square brackets or dot notation in the Flask web framework? Both seem to work, for example:
In the Python script I can set session['username'] = 'Geraint'
. I can then access it the template using {{ session['username'] }}
or {{ session.username }}
What's the difference between the two? The docs seem to favour the dot notation so should that be used in all cases?
This is a feature of Jinja2, see the Variables section of the Template Designer documentation:
You can use a dot (
.
) to access attributes of a variable in addition to the standard Python__getitem__
“subscript” syntax ([]
).
This is a convenience feature:
For the sake of convenience,
foo.bar
in Jinja2 does the following things on the Python layer:
- check for an attribute called bar on foo (
getattr(foo, 'bar')
)- if there is not, check for an item
'bar'
in foo (foo.__getitem__('bar')
)- if there is not, return an undefined object.
foo['bar']
works mostly the same with a small difference in sequence:
- check for an item
'bar'
in foo. (foo.__getitem__('bar')
)- if there is not, check for an attribute called bar on foo. (
getattr(foo, 'bar')
)- if there is not, return an undefined object.
This is important if an object has an item and attribute with the same name. Additionally, the
attr()
filter only looks up attributes.
So if you use the attribute access ({{ session.username }}
) then Jinja2 will first look for the attribute, then for the key. Since the Flask session
object is a dictionary, this means you could potentially end up with the wrong result; if you have stored data under the key get
in the session, session.get
returns a dictionary method, but session['get']
would return the actual value associated with the 'get'
key.