【问题标题】:django - how to do this with kwargsdjango - 如何用 kwargs 做到这一点
【发布时间】:2013-05-21 13:31:41
【问题描述】:

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

我有这个 kwargs dic:

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

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

我想,我会像这样为name__startswith 设置distinct() in 循环:

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

然后动态查询所有:

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

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

如何动态地执行这两个查询?

【问题讨论】:

    标签: python django keyword-argument


    【解决方案1】:

    django 查询集是lazy,所以实际查询不是evaluated until you use the data.

    allthings = Thing.objects.filter(**kwargs)
    
    if 'name__startswith' in kwargs:
      allthings = allthings.distinct('id')   
    

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


    来自docs

    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。

    【讨论】:

    • 谢谢,我决定在所有查询上distinct,这不会损坏任何东西。无论如何感谢您的帮助
    • 使用distinct 会显着减慢您的查询速度:stackoverflow.com/questions/1977739/…
    【解决方案2】:

    您可以使用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

    【讨论】:

    • 但你是distinct 也为color__iexact,我也需要name__startswith
    • 不,distinct 需要一个列名,您只需提供您想要在其上具有 distinct 的列。将我的答案更新为按名称区分
    • 哦,好的,太好了。太感谢了。我对Q 一无所知。你给了我新的方法。感谢吨
    • 更明确地说,它不会在color 上做不同的事情,如果你想要颜色和名称的不同组合,你可以做distinct('name', 'color')
    猜你喜欢
    • 2017-09-27
    • 1970-01-01
    • 1970-01-01
    • 2011-06-11
    • 2011-03-12
    • 2019-09-19
    • 2012-12-12
    • 2019-04-30
    • 2017-09-23
    相关资源
    最近更新 更多