我正在尝试在Django的查询集中使用经典数据库GROUP_BY。
我已经看过How to query as GROUP BY in django?,但区别在于:
values()
返回的事物的类型)。我的模特:
class CitiesTable(models.Model):
country = models.TextField()
region_or_state = models.TextField()
city = models.TextField()
我希望按country
进行分类,然后在其中region_or_state
进行分类,其中包含city
的列表:
我想要
{'USA':
{'California': ['San Francisco', 'Los Angeles', ...],
'Texas': ['Dallas', 'Houston', ...},
'Germany':
{'Bavaria': ['Munich', 'Nuremberg', ...}
}
但是,如前所述,列表中的城市应该是对象。
我没有找到如何在Django中获取它,所以在python中使用itertools
,我已经成功用于外部GROUP_BY:
(帮助我:How to convert tuple to a multi nested dictionary in python?):
from itertools import groupby
def show_cities(request):
queryset = CitiesTable.objects.all()
grouped_cities = []
unique_countries = []
for k, g in groupby(queryset, lambda x: x.country):
grouped_cities.append(list(g))
unique_countries.append(k)
return render(request, 'cities/show_cities.html',
{'cities':grouped_cities, 'countries':unique_countries})
但我没有设法将所有城市对象归为region_or_state
。
答案 0 :(得分:1)
我担心我不知道如何用django的查询集来解决这个问题。可能没有解决方案,或者它可能涉及使用未记录的功能。
但是,python解决方案在大多数情况下都可以。无论如何,Django可能不得不做类似的事情。
您当前的代码可能存在轻微问题。在使用itertools.groupby
之前,您几乎总是要对条目进行排序 - 这是一个常见的陷阱,以至于我很惊讶它不会自动排序。 Groupby遍历iterable,并在每次键值更改时创建一个新组。因此,要完全对可迭代组合,您需要先按键排序。
您可以在此处使用数据库进行排序,只需使用groupby
两次:
queryset = CitiesTable.objects.order_by('country', 'region_or_state')
countries_dict = {}
for country, group in groupby(queryset, lambda x: x.country):
countries_dict[country] = {}
for region, inner_group in groupby(group, lambda x: x.region_or_state):
countries_dict[country][region] = list(inner_group)