Reputation: 1162
I have the following issue with groupby
function in jinja:
I have a list of Dicts, where one key inside each is [Tech]:**some tech value**
and I want to sort and group in a custom manner, let's say I have
tech_order = [tech2, tech5, tech1, tech3, tech4] #these values are arbitrary just for example
When I do this using python only
def custom_sort_list_dictated(Dict, Key, list_order):
Dict = Dict.sort(key=lambda k:list_order.index(k[Key]))
#Written as function because I pass it later in jinja2.Environment.globals.update()
custom_sort_list_dictated(My_list_of_dicts, 'Tech', tech_order)
#This works and sorts my dictionaries correctly
for key, value in itertools.groupby(Anforderungen, key=itemgetter('Tech')):
Val_list.append(list(value)) # Store group iterator as a list
Key_list.append(key)
Using itertools.groupby
in python will group my custom sorted dictionaries according to my tech_order
list and group them conserving the order.
This however is not the case in jinja2, I have the following template:
{{ custom_sort_list_dictated(My_list_of_dicts, 'Tech', tech_order) or '' }}
{% for Tech, group_by_tech in My_list_of_dicts|groupby('Tech') %}
{{ jinja_append_array(Val_Array, list(group_by_tech)) or '' }}
{{ jinja_append_array(Key_Array, Tech) or '' }}
{% endfor %}
However groupby
in jinja2 sorts my dictionaries back in alphabetical order, unlike itertools.groupby
in python. Is there a way not to have this happen?
I know the issue is jinja2 groupby
because just calling:
{% for Tech, group_by_tech in My_list_of_dicts|groupby('Tech') %}
{{ Tech + " ~~ " }}
{% endfor %} #This prints my techs in alphabetical order which is not consistent with itertools.groupby
PS: jinja_append_array
and custom_sort_list_dictated
are passed from python to jinja using jinja2.Environment.globals.update()
Upvotes: 0
Views: 2142
Reputation: 1162
Ended up making my own groupby()
custom function and passing it into inja2.Environment.globals.update()
as follows:
import jinja2
import itertools
from operator import itemgetter
def custom_jinja_groupby(Dict, Key_list, Val_list, group_filter, parse_filter):
temp_array = []
for key, value in itertools.groupby(Dict, key=itemgetter(group_filter)):
Key_list.append(key)
for content in value:
Parse_Info_Dictionary(content, parse_filter) #another custom function as I needed to make some changes to my grouping
temp_array.append(content)
Val_list.append(temp_array)
temp_array=[]
template_file_loader = jinja2.FileSystemLoader('{}'.format(path_to_jinja_template_folder))
env = jinja2.Environment(loader = template_file_loader)
env.globals.update(custom_jinja_groupby = custom_jinja_groupby)
I can use this in my Jinja file as follows:
{{ custom_jinja_groupby(My_Dict_To_Group, Key_Array, Val_Array, 'group_by_This', 'Custom_function_at_This') or '' }}
Note the or ''
is used because otherwise it will print None into your rendered file, this will have it print nothing and still perform the function changes. The goal is getting Key_Array
and 'Val_Array' which are passed by reference I guesss inside the jinja file but this will pretty much keep your custom ordering after grouping. Hope this helps someone later on.
Upvotes: 1