我要做的是编写一个筛选出唯一父/名组合的查询集。我只对第一次出现一个独特的父母名称感兴趣。
ID PARENT TYPE LIBTYPE NAME
1 1 project 1 book_a
4 4 project 2 book_b
5 4 project 2 book_c
6 4 project 2 book_d
7 4 project 4 book_c
8 5 project 2 book_e
9 5 project 4 book_e
10 7 project 0 book_f
11 7 project 0 book_g
12 7 project 6 book_h
13 6 user 1 book_i
14 6 project 1 book_j
15 6 project 1 book_k
16 7 project 5 book_h
17 7 project 8 book_h
18 7 project 7 book_h
19 7 project 9 book_h
20 7 project 1 book_h
21 8 project 1 book_a
所以我们从一个基本的查询集开始..
vars = Variants.objects.filter(type="project")
这删除了单独的用户..现在在纯python我会这样做来过滤这个吸盘。
vars = Variants.objects.filter(type="project")
new_vars = []
for idx, var in vars.enumerate():
if var.name not in new_vars:
new_vars.append((var.parent,var.name))
else:
del vars[idx]
最后我应该得到以下ID(1,4,5,6,8,10,11,13,14,15,21)显然我不能枚举一个Queryset加上我是确定有一种方法可以在Django中过滤它。
有人可以说明如何在Django中有效地做到这一点吗?
答案 0 :(得分:1)
我所谓的“纯Python”解决方案毫无意义,我担心。首先,enumerate
是内置的,因此您可以调用enumerate(vars)
;其次,你将一个元组追加到new_vars,因此var in new_vars
永远不会是真的;第三,我看不出你要用del
语句做什么 - 你永远不应该修改你正在迭代的东西。
Python中更好的解决方案可能是这样的:
var_dict = {}
for var in vars:
if var.name not in var_dict:
var_dict[var.name] = var
return var_dict.values()
与查询集一样有效。
但是,如果我理解正确,那么您将使用数据库级别的解决方案。这是不可能的,因为聚合函数适用于所选的整行。您可以获取(parent, name)
的唯一值,但您也无法获取ID - 因为(id, parent, name)
不是唯一的组合。
答案 1 :(得分:0)
这就是我做过的事 - 丹是对的,我是一个骨头......
projects = Variant.objects.filter(type="project")
filter_list, uniq_projs = [], []
for project in projects:
if (project.name, project.parent) not in uniq_projs:
uniq_projs.append((project.name, project.parent))
filter_list.append(project.id)
projects = Variant.objects.filter(type="project", id__in=filter_list).order_by('parent__name')
感觉很蠢..