2013-05-21 40 views
2

我想知道当我做查询时触摸db。更确切地说,是在查询执行时:django - 如何与kwargs做到这一点

我有这个kwargs DIC:

kwargs = {'name__startswith':'somename','color__iexact':'somecolor'} 

但仅限于name__startswith查询,我需要distinct()。而不是为color__iexact

我想,我会在环路name__startswithdistinct()这样设置:

for q in kwargs: 
    if q == 'name__startswith': 
    Thing.objects.filter(name__startswith=somename).distinct('id') 

,然后查询所有动态:

allthings = Thing.objects.filter(**kwargs) 

但这是有点错了,我似乎是在这里做两件不同的事情..

我该如何动态地做这两个查询?

回答

4

Django的查询集为lazy,因此实际查询不evaluated until you use the data.

allthings = Thing.objects.filter(**kwargs) 

if 'name__startswith' in kwargs: 
    allthings = allthings.distinct('id') 

没有查询应上述unitl你实际使用的数据进行预制。 - 创建一个查询集不涉及任何数据库活动的行为

查询集是懒惰:你希望做


docs这是伟大的过滤查询。您可以整天将过滤器堆叠在一起,并且在评估QuerySet之前,Django不会真正运行查询。看看这个例子:

>>> q = Entry.objects.filter(headline__startswith="What") 
>>> q = q.filter(pub_date__lte=datetime.date.today()) 
>>> q = q.exclude(body_text__icontains="food") 
>>> print(q) 

虽然这看起来像三个数据库访问,实际上它访问数据库只有一次,在最后一行(打印(Q))。一般来说,直到你“询问”它们之前,QuerySet的结果都不会从数据库中获取。当你这样做时,通过访问数据库来评估QuerySet。有关确切何时进行评估的更多详细信息,请参阅何时评估QuerySet。

+0

感谢的人,我决定'上的所有查询,这亘古不变的伤害任何'distinct''。感谢您的帮助无论如何 – doniyor

+1

使用'distinct'可以显着减慢您的查询:http://stackoverflow.com/questions/1977739/is-distinct-an-expensive-query-in-django –

1

您可以使用models.Q在django中创建动态查询。

query = models.Q(name__startswith=somename) 

query &= models.Q('color__iexact':'somecolor') 

all_things = Thing.objects.filter(query).distinct('name') 

又读 Constructing Django filter queries dynamically with args and kwargs

+0

但你是''distinct''也''color__iexact',我还需要'name__startswith' – doniyor

+0

不,不同,需要一个列名,你可以提供你想要有一个独特的列。更新我的答案,以明确的名称 –

+0

哦,好吧,太棒了。非常感谢。我对“Q”没有任何了解。你给了我新的方法。谢谢。 – doniyor