I have a Jinja2 dictionary and I want a single expression that modifies it - either by changing its content, or merging with another dictionary.
>>> import jinja2
>>> e = jinja2.Environment()
Modify a dict: Fails.
>>> e.from_string("{{ x[4]=5 }}").render({'x':{1:2,2:3}})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "jinja2/environment.py", line 743, in from_string
return cls.from_code(self, self.compile(source), globals, None)
File "jinja2/environment.py", line 469, in compile
self.handle_exception(exc_info, source_hint=source)
File "<unknown>", line 1, in template
jinja2.exceptions.TemplateSyntaxError: expected token
'end of print statement', got '='
Two-stage update: Prints superfluous "None".
>>> e.from_string("{{ x.update({4:5}) }} {{ x }}").render({'x':{1:2,2:3}})
u'None {1: 2, 2: 3, 4: 5}'
>>> e.from_string("{{ dict(x.items()+ {3:4}.items()) }}").render({'x':{1:2,2:3}})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "jinja2/environment.py", line 868, in render
return self.environment.handle_exception(exc_info, True)
File "<template>", line 1, in top-level template code
TypeError: <lambda>() takes exactly 0 arguments (1 given)
Use dict(x,**y)
: Fails.
>>> e.from_string("{{ dict((3,4), **x) }}").render({'x':{1:2,2:3}})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "jinja2/environment.py", line 868, in render
return self.environment.handle_exception(exc_info, True)
File "<template>", line 1, in top-level template code
TypeError: call() keywords must be strings
So how does one modify the dictionary x
in Jinja2 by changing an attribute or merging with another dictionary?
This question is similar to: How can I merge two Python dictionaries as a single expression? -- insofar as Jinja2 and Python are analogous.
Using | in Python 3.9 In the latest update of python now we can use “|” operator to merge two dictionaries. It is a very convenient method to merge dictionaries. Example: Python3.
As dictionary is also iterable, we can use the chain() function from itertools class and merge two dictionaries. The return type of this method will be an object, and hence, we can convert the dictionary using the dict() constructor.
I found another solution without any extension.
{% set _dummy = x.update({4:5}) %}
It makes x updated. Don't use _dummy.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With