Johnny Metz
Johnny Metz

Reputation: 6035

jinja2: reject a specific attribute from a dictionary

I have the following dictionary:

d = {'name': 'Johnny', 'age': 23, '_id': 167, 'sport': 'golf'}

Using jinja2 I want to filter out (or reject) the _id key so I get the following dictionary (note this _id field is dynamic so I want to reject the key no matter what it's equal to):

{'name': 'Johnny', 'age': 23, 'sport': 'golf'}

I've tried using the built-in filters reject and rejectattr but it's not working as expected. This is what I've tried so far:

{{ d | rejectattr('_id') }}
# <generator object select_or_reject>
{{ d | rejectattr('_id', 'defined') }}
# <generator object select_or_reject>
{{ d | reject('_id', 'defined') }}
# <generator object select_or_reject>

Upvotes: 7

Views: 7141

Answers (2)

cov
cov

Reputation: 165

Here are two approaches. The first adapts dasmy's rejectattr-from-list-of-tuples approach to use the dict global function rather than the list filter. The second approach renders characters that will be interpreted as a dictionary by ast.native_eval, which is called by NativeTemplate.render(). (Not only is the second approach already more verbose, but it may need to be expanded to handle all possible types.)

from jinja2.nativetypes import NativeTemplate


def render_d(template):
    print(
        NativeTemplate(template).render(
            d={"name": "Johnny", "age": 23, "_id": 167, "sport": "golf"}
        )
    )


render_d("{{dict(d.items() | rejectattr(0, 'equalto', '_id'))}}")

render_d(
    """
    {
        {% for key, value in d.items() -%}
            {% if key != "_id" -%}
                {% if value is string -%}
                    "{{key}}": "{{value}}",
                {% else -%}
                    "{{key}}": {{value}},
                {% endif -%}
            {% endif -%}
        {% endfor -%}
    }
    """.strip()
)

Upvotes: 2

dasmy
dasmy

Reputation: 597

Maybe slightly late, but something along the lines of

{{ d.items() | rejectattr('0', 'equalto', '_id') | list }}

might help: It converts the dict into a list of tuples, and rejects entries depending on value of the first entry in each tuple. The final |list might not be necessary, depending on your use-case. It just converts the generator object created by rejectattr into a list again.

Upvotes: 2

Related Questions