2011-07-05 128 views
0

我想要做的是编写一个查询集,过滤出独特的父/名组合。我只对第一次出现一个独特的父母名称感兴趣。Django过滤一个查询集 -

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)很显然,我不能在查询集枚举再加上我相信有一种方法可以在Django中进行过滤。

有人可以请讲解如何有效地在Django中做到这一点?

+1

一个不相关的小窍门:我会避免使用'vars'作为变量/函数名称,因为它会覆盖内置函数。见http://docs.python.org/library/functions.html –

回答

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() 

与一个queryset的作品一样好。

但是,如果我理解正确,那么您是在使用db级解决方案。这是不可能的,因为聚合函数在被选择的整个行上工作。您可以获得(parent, name)的唯一值,但您无法获得该ID - 因为(id, parent, name)不是唯一的组合。

+0

睡得太少 - 我很尴尬。我感谢你浪费你的时间来展示我 - 我也意识到了严重的错误。接受和关闭。谢谢丹! FWIW--唯一性是基于名字和父母,而不仅仅是名字。无论我不再需要帮助 - 我也不配。 – rh0dium

+0

不要对自己这么辛苦!这个论坛是为了提出问题,而这远远不是一个坏问题或者你没有努力。 –

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') 

感觉如此愚蠢..