3

我想知道在进行查询时何时触摸 db。更准确地说,查询何时执行:

我有这个 kwargs dic:

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

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

我想,我会像这样设置name__startswithindistinct()循环:

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

然后动态查询所有:

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

但这在某种程度上是错误的,我似乎在这里做两件不同的事情..

我怎样才能动态地做这两个查询?

4

2 回答 2

5

django 查询集是惰性的,因此在您使用数据之前不会评估实际查询。

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

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

在您实际使用数据之前,不应执行任何查询。这非常适合按照您的意愿过滤查询


文档

QuerySet 是惰性的——创建 QuerySet 的行为不涉及任何数据库活动。您可以整天将过滤器堆叠在一起,并且在评估 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)

虽然这看起来像三个数据库命中,但实际上它只命中数据库一次,在最后一行 (print(q))。通常,在您“请求”查询集的结果之前,不会从数据库中获取它们。执行此操作时,将通过访问数据库来评估 QuerySet。有关何时进行评估的更多详细信息,请参阅何时评估 QuerySet。

于 2013-05-21T13:43:25.043 回答
1

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

query = models.Q(name__startswith=somename)

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

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

另请阅读 使用 args 和 kwargs 动态构建 Django 过滤器查询

于 2013-05-21T13:50:26.690 回答