89

I have a python dictionary:

settings = {
   "foo" : "baz",
   "hello" : "world"
}

This variable settings is then available in the Jinja2 template.

I want to check if a key myProperty exists in the settings dict within my template, and if so take some action:

{% if settings.hasKey(myProperty) %}
   takeSomeAction();
{% endif %}

What is the equivalent of hasKey that I can use?

Amal Antony
  • 6,477
  • 14
  • 53
  • 76

4 Answers4

178

Like Mihai and karelv have noted, this works:

{% if 'blabla' in item %}
  ...
{% endif %}

I get a 'dict object' has no attribute 'blabla' if I use {% if item.blabla %} and item does not contain a blabla key

tshalif
  • 2,277
  • 2
  • 15
  • 10
  • 3
    Same for me. In my particular case I'm using Jinja2 inside Ansible. – chesterbr Jan 14 '17 at 15:53
  • 1
    Using jinja2 inside Ansible. Nothing helps. Both `{% if 'blabla' in item %}` and `{% if item.blabla %}` return the same `'dict object' has no attribute 'blabla'` wtf??? – Drew Apr 08 '18 at 06:41
  • `argument of type 'StringField' is not iterable`. Does not work for me – blkpingu Oct 14 '19 at 10:50
  • Is `item` supposed to be a dictionary in this answer? That's a confusing name (an item is a key/value pair inside a dictionary). Sorry if I'm missing something. – Seub Nov 20 '22 at 00:32
39

You can test for key definition this way:

{% if settings.property is defined %}

#...
{% endif %}
ma3oun
  • 3,681
  • 1
  • 21
  • 33
15

This works fine doesn't work in cases involving dictionaries. In those cases, please see the answer by tshalif. Otherwise, with SaltStack (for example), you will get this error:

Unable to manage file: Jinja variable 'dict object' has no attribute '[attributeName]'

if you use this approach:

{% if settings.myProperty %}

note:
Will also skip, if settings.myProperty exists, but is evaluated as False (e.g. settings.myProperty = 0).

devinbost
  • 4,658
  • 2
  • 44
  • 57
Mihai Zamfir
  • 2,167
  • 4
  • 22
  • 37
  • 1
    Can `myProperty` be a variable in the approach above? – Amal Antony Jan 02 '15 at 09:51
  • 4
    Yes, a key in a dictionary. Is the equivalent of ``hasKey``. And btw, hasKey is deprecated. Use ``in`` instead – Mihai Zamfir Jan 02 '15 at 09:52
  • 13
    when setting.myProperty exists, but it is equal to zero (integer 0) or to the boolean value False, this if test not for 'hasKey'. This means you need: ``{% if 'myProperty' in settings %}`` – karelv Sep 18 '15 at 21:03
  • 9
    this doesn't work for me (at least working with ansible). i found i needed `{% if settings.myProperty is defined %}`. – ryantuck Feb 09 '16 at 20:21
  • 9
    I don't get why this is accepted as answer - it throws an error if the dict is missing the key. Please correct the answer. – Florian Neumann Sep 15 '17 at 12:32
  • 1
    @MihaiZamfir There is no reason to interpret my commentary with excessive emotion. tshalif prooved the failure - and his answer seems to be the more robust one and even if "the" answer is right for a subset of use cases, it should in my opinion at least reflect that it might not fit for all use cases. – Florian Neumann Sep 18 '17 at 12:46
  • 1
    Looks like this answer fails if `settings.myProperty` is an empty dictionary/list. – Edward Fung Oct 19 '17 at 08:52
  • 1
    Answer by @RyanTuck is the most correct and works regardless of the Boolean (True/False) status of `myProperty` :: `{% if settings.myProperty is defined %}` – Marc Tamsky Aug 08 '18 at 06:32
  • fails when the key is not existent – ma3oun Oct 29 '18 at 14:23
1

Actually, in the style of Python, if you do a simple if statement, it will work:

{% if settings.foo %}
Setting Foo: {{ settings.foo }}
{% endif %}
{% if settings.bar %}
Setting Bar: {{ settings.bar }}
{% endif %}
{% if settings.hello %}
Setting Hello: {{ settings.hello }}
{% endif %}

Output:

Setting Foo: baz
Setting Hello: world

Cheers!

NFSpeedy
  • 161
  • 2
  • 10