开发者

Django filtering a queryset -

What I am trying to do is to write a query set that filters out unique parent/name combinations. I'm only interested in the first occurance of a unique parent name.

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     proje开发者_开发问答ct     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

So we started with a basic queryset..

vars = Variants.objects.filter(type="project")

This removed out the lone user.. Now in pure python I would just do this to filter this sucker.

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]

In the end I should end up with the following ID's (1,4,5,6,8,10,11,13,14,15,21) Obviously I can't enumerate on a Queryset plus I'm sure there is a way to filter this in Django.

Can someone please shed some light on how to efficiently do this in Django?


Your so-called "pure Python" solution makes no sense, I'm afraid. For a start, enumerate is a built-in, so you would call enumerate(vars); secondly, you append a tuple to new_vars so var in new_vars will never be True; and thirdly, I can't see what you're trying to do with that del statement - you should never modify something you're iterating through.

A better solution in Python might be something like this:

var_dict = {}
for var in vars:
    if var.name not in var_dict:
        var_dict[var.name] = var

return var_dict.values()

which works just as well with a queryset.

If I understand correctly, though, you're after a db-level solution. That's not possible, as aggregation functions work on the whole row being selected. You can get the unique values for (parent, name) but you can't get the ID as well - because (id, parent, name) is not a unique combination.


Here is what I did do - Dan was right and I was a bone-head..

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

Feeling so dumb..

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜