【问题标题】:Django - was queryset filtered using some parameters or notDjango - 是否使用某些参数过滤了查询集
【发布时间】:2019-03-04 17:24:15
【问题描述】:

与 python - django 框架相关的问题,可能是有经验的 django 开发人员。谷歌了一段时间,也在 django 查询集本身中寻找,但没有答案。是否可以知道查询集是否已被过滤,如果是,则获取过滤参数的键值? 我正在开发具有大量过滤器集的 Web 系统,如果某些过滤器受到影响,我必须预定义一些用户后台行为。

【问题讨论】:

  • 你在查询集中有选择查询..你可以从中判断是否有过滤器

标签: python django filter django-queryset


【解决方案1】:

是的,但据我所知,这没有记录在案,您可能应该使用它。此外,如果您需要从 QuerySet 获取它,我觉得它看起来像糟糕的设计。

对于QuerySet,例如qs,可以获取.query属性,然后查询.where属性。该属性的 truthiness 检查该节点(该属性是 WhereNode,它是查询语法中的一个节点)是否有子节点(这些子节点是单独的 WHERE 条件或组这样的条件),因此做了一些过滤。

例如:

qs = Model.objects.all()
bool(qs.query.where)   # --> False

qs = Model.objects.filter(foo='bar')
bool(qs.query.where)   # --> True

如果您检查WhereNode,您可以看到组成它的元素,例如:

>>> qs.query.where
<WhereNode: (AND: <django.db.models.lookups.Exact object at 0x7f2c55615160>)>

通过观察孩子,我们甚至可以获得细节:

>>> qs.query.where.children[0]
>>> c1.lhs
Col(app_model, app.Model.foo)
>>> c1.lookup_name
'exact'
>>> c1.rhs
'bar'

但是这个符号相当神秘。此外,WhereNode 本身不是合取的(AND),它也可以是析取的(OR),并且没有说会进行任何过滤(因为测试可以很简单是真的,比如1 &gt; 0)。因此,我们只查询 SQL 查询中是否有非空的WHERE。不是这个查询是否会以任何方式限制查询集(尽管您当然可以检查WhereNode,看看是否成立)。

请注意,某些约束不是WHERE 的一部分,例如,如果您创建JOIN,您将执行ON,但这不是WHERE 子句。

然而,据我所知,由于上述内容没有得到广泛的记录,因此依赖它可能不是一个好主意,因为这意味着它很容易改变,因此不再起作用。

【讨论】:

    【解决方案2】:

    您可以使用query 属性(即queryset.query)来获取SQL 查询中使用的数据(输出不是完全有效的SQL)。

    您还可以使用queryset.query.__dict__ 以字典格式获取该数据。

    【讨论】:

      【解决方案3】:

      我同意 Willem Van Onsen 的观点,因为不能保证将来可以访问查询对象的内部。现在是正确的,但可能会改变。

      但是在这条路的中途,您可以使用以下内容:

      is_filtered_query = bool(' WHERE ' in str(queryset.query))
      

      这几乎可以完成这项工作!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-22
        • 2019-04-15
        • 2011-09-29
        相关资源
        最近更新 更多