我需要重新组合一个列表,而不是按每个结果列表的项目数显示排序结果。
类似的东西:
{% regroup car_models by make as car_models_by_make %}
{% for make in car_models_by_make|dictsort:"???" --> the problem %}
{{ make.grouper }} ({{ make.list|length }}) <br>
{% endfor %}
所以如果数据是:
[
('panda','fiat'),
('500','fiat'),
('focus','ford')
]
结果应该是:
fiat 2
ford 1
我试过:dictsort:“make.list.count”,“make.list.length”,“make.list | length”..没有做过工作..
答案 0 :(得分:2)
我认为dictsort
不适合这里。
>>> l = [('panda', 'fiat'), ('500', 'fiat'), ('focus', 'ford')]
>>> values = [i[1] for i in l]
>>> from collections import Counter
>>> c = Counter(values)
>>> c.most_common()
[('fiat', 2), ('ford', 1)]
您可以定义自己的template tags,
from django import template
from collections import Counter
register = template.Library()
@register.filter
def my_sort(l):
values = [i[1] for i in l]
c = Counter(values)
return c.most_common()
答案 1 :(得分:1)
您应该将数据作为dicts的排序列表传递给模板:
>>> data = [ ('panda','fiat'),
... ('500','fiat'),
... ('focus','ford') ]
>>>
>>> from itertools import groupby
# note that we need to sort data before using groupby
>>> groups = groupby(sorted(data, key=lambda x: x[1]), key=lambda x:x[1])
# make the generators into lists
>>> group_list = [(make, list(record)) for make, record in groups]
# sort the group by the number of car records it has
>>> sorted_group_list = sorted(group_list, key=lambda x: len(x[1]), reverse=True)
# build the final dict to send to the template
>>> sorted_car_model = [{'make': make, "model": r[0]} for (make, records) in sorted_group_list for r in records]
>>> sorted_car_model
[{'make': 'fiat', 'model': 'panda'}, {'make': 'fiat', 'model': '500'}, {'make': 'ford', 'model': 'focus'}]
这里的目标是对列表进行排序,以便按照他们生产的模型数量对汽车制造商进行排名。
然后,使用:
{% regroup car_models by make as make_list %}
{% for item in make_list %}
{{ item.grouper }} ({{ item.list|length }}) <br>
{% endfor %}
得到:
fiat 2
ford 1
参考:regroup
如果您的数据与评论中的数据类似:
>>> car_models = [
... {'make': 'ford', 'model': 'focus'},
... {'make': 'fiat', 'model': 'panda'},
... {'make': 'ford', 'model': '500'},
... {'make': 'fiat', 'model': '500'},
... {'make': 'opel', 'model': '500'},
... {'make': 'opel', 'model': '500'},
... {'make': 'opel', 'model': '500'},
... ]
>>>
>>> groups = groupby(sorted(car_models, key=lambda x:x['make']), key=lambda x:x['make'])
>>> groups = [(make, list(x)) for make, x in groups]
>>> sorted_group_list = sorted(groups, key=lambda x:len(x[1]), reverse=True)
>>> sorted_car_model = [{'make': make, 'model': r['model']} for (make, records) in sorted_group_list for r in records]
>>> sorted_car_model
[{'make': 'opel', 'model': '500'}, {'make': 'opel', 'model': '500'}, {'make': 'opel', 'model': '500'}, {'make': 'fiat', 'model': 'panda'}, {'make': 'fiat', 'model': '500'}, {'make': 'ford', 'model': 'fo
cus'}, {'make': 'ford', 'model': '500'}]
或者,您可以将结果传递给模板,如下所示:
>>> from collections import Counter
>>> l = [r['make'] for r in car_models]
>>> c = Counter(l)
>>> result = [{k: v} for k,v in dict(c).iteritems()]
>>> result = sorted(result, key=lambda x: x.values(), reverse=True)
[{'opel': 3}, {'fiat': 2}, {'ford': 2}]
然后,将此结果传递给模板,只需渲染结果:
{% for r in result %}
{% for k,v in r.items %}
{{ k }} {{ v }}
{% endfor %}j
{% endfor %}
然后你会得到:
opel 3
fiat 2
ford 2
答案 2 :(得分:0)
使用此模板标签我做了:
@register.filter()
def groups_sort(groups):
groups.sort(key=lambda group: len(group['list']))
return groups
@register.filter()
def groups_sort_reversed(groups):
groups.sort(key=lambda group: len(group['list']), reverse=True)
return groups
可以这样做:
{% load custom_templatetags %}
{% regroup car_models by make as car_models_by_make %}
{% for make in car_models_by_make|groups_sort_reversed %}
{{ make.grouper }} ({{ make.list|length }}) <br>
{% endfor %}
会给你
fiat 2
ford 1
使用groups_sort将为您提供:
ford 1
fiat 2
这当然适用于Django模型
享受