django 中的嵌套 GROUP BY:返回对象
Nested GROUP BY in django: returning Objects
我正尝试在我的 Django 查询集上使用经典数据库 GROUP_BY。
我已经看过 How to query as GROUP BY in django? 但区别是:
- 我需要获取 对象 的字典,而不是值(实际上不是
values()
返回的事物类型)。
- 我需要 嵌套 字典(即,我需要 GROUP_BY on GROUP_BY)。
我的模型:
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', ...}
}
但是在这里,如前所述,列表中的城市应该是 Objects.
我没有找到如何在 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
中对所有城市对象进行分组。
恐怕我不知道如何用 django 的查询集解决这个问题。可能没有解决方案,或者如果有,可能涉及使用未记录的功能。
但是,python 解决方案在大多数情况下都可以正常工作。无论如何,Django 可能不得不自己做类似的事情。
看起来您当前的代码可能存在一些小问题。在使用 itertools.groupby
之前,您几乎应该总是对您的条目进行排序 - 这是一个常见的陷阱,以至于我很惊讶它不会自动排序。 Groupby 遍历可迭代对象,并在每次键的值发生变化时创建一个新组。因此,要对一个可迭代对象进行完全分组,您需要先按键排序。
这里可以使用数据库进行排序,只需使用两次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)
我正尝试在我的 Django 查询集上使用经典数据库 GROUP_BY。
我已经看过 How to query as GROUP BY in django? 但区别是:
- 我需要获取 对象 的字典,而不是值(实际上不是
values()
返回的事物类型)。 - 我需要 嵌套 字典(即,我需要 GROUP_BY on GROUP_BY)。
我的模型:
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', ...}
}
但是在这里,如前所述,列表中的城市应该是 Objects.
我没有找到如何在 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
中对所有城市对象进行分组。
恐怕我不知道如何用 django 的查询集解决这个问题。可能没有解决方案,或者如果有,可能涉及使用未记录的功能。
但是,python 解决方案在大多数情况下都可以正常工作。无论如何,Django 可能不得不自己做类似的事情。
看起来您当前的代码可能存在一些小问题。在使用 itertools.groupby
之前,您几乎应该总是对您的条目进行排序 - 这是一个常见的陷阱,以至于我很惊讶它不会自动排序。 Groupby 遍历可迭代对象,并在每次键的值发生变化时创建一个新组。因此,要对一个可迭代对象进行完全分组,您需要先按键排序。
这里可以使用数据库进行排序,只需使用两次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)