Python 如何编辑查询集的筛选器列表

Python 如何编辑查询集的筛选器列表,python,django,Python,Django,此功能在我列出搜索结果的视图中使用。在我的搜索表单中,我使用外键搜索一些ModelChoiceFields。通常的工作流程意味着将我们当前的搜索变得越来越精确,所以为了禁用许多不相关的结果,我尝试删除一些条目,如果没有其他搜索参数更改,这些条目将不会返回任何结果 我使用对象查询集来限制一些下拉列表中的命题。 我使用这些下拉列表按外键筛选对象列表 我的filter函数参数是一个对象查询集,目前: class MySearchForm(Form): things = ModelChoiceF

此功能在我列出搜索结果的视图中使用。在我的搜索表单中,我使用外键搜索一些ModelChoiceFields。通常的工作流程意味着将我们当前的搜索变得越来越精确,所以为了禁用许多不相关的结果,我尝试删除一些条目,如果没有其他搜索参数更改,这些条目将不会返回任何结果

我使用对象查询集来限制一些下拉列表中的命题。 我使用这些下拉列表按外键筛选对象列表

我的filter函数参数是一个对象查询集,目前:

class MySearchForm(Form):
    things = ModelChoiceField(queryset=models.Thing.objects.none())
    def __init__(self, *args, **kwargs):
        my_objects_queryset = kwargs.pop('my_objects_queryset',models.Thing.objects.all())
        super(MySearchForm, self).__init__(*args, **kwargs)
        self.fields['things'].queryset = \
            models.Thing.objects.filter(object__in=my_objects_queryset).distinct()
我的问题是如何从现有查询集中删除“where close”。 在这里,我想从我的\u objects\u queryset中删除,其中关闭了按thing=ForeignKeymodels.thing过滤的过滤器

可能吗

类似于列出查询集的所有筛选器并动态编辑/删除它们的方法。

简短回答: 不,你不能那样做

长答覆: 从理论上讲,这在某种程度上是可能的,但肯定是不可取的

我还没有完全研究django源代码,因此下面是一个简单的向上爬调用树的结果

查看,筛选并排除返回queryset本身的克隆,并使用clone.query.add\u q添加新规则

clone.query是一个新规则,而该方法添加的新规则本质上是一个的根节点

如何将新节点添加到树中取决于规则是使用AND还是or子句连接。这一点很重要,因为它会影响最终SQL查询的正确性

因此,要列出分配给queryset的过滤器,只需了解queryset.query.where树是如何表示的

当然,难点在于删除过滤器,这样就不会影响其余规则。我将不提供解决办法,因为无法保证执行情况不会改变,从而使解决办法无效。我怀疑这是可能的,但它闻起来有一种只有出于学术兴趣才应该做的事情,或者根本不应该做。

简短回答: 不,你不能那样做

长答覆: 从理论上讲,这在某种程度上是可能的,但肯定是不可取的

我还没有完全研究django源代码,因此下面是一个简单的向上爬调用树的结果

查看,筛选并排除返回queryset本身的克隆,并使用clone.query.add\u q添加新规则

clone.query是一个新规则,而该方法添加的新规则本质上是一个的根节点

如何将新节点添加到树中取决于规则是使用AND还是or子句连接。这一点很重要,因为它会影响最终SQL查询的正确性

因此,要列出分配给queryset的过滤器,只需了解queryset.query.where树是如何表示的

当然,难点在于删除过滤器,这样就不会影响其余规则。我将不提供解决办法,因为无法保证执行情况不会改变,从而使解决办法无效。我怀疑这是可能的,但它闻起来有些东西只应该出于学术兴趣,或者根本不应该做。

这里有一些黑客攻击

您可以通过如下重置当前过滤器来绕过它:

from django.db.models.sql.where import WhereNode

qs = YourModel.objects.filter(column=1).all()
qs.query.where = WhereNode() # resets current filters
qs.all() # now you can apply new filters
这里有些黑客

您可以通过如下重置当前过滤器来绕过它:

from django.db.models.sql.where import WhereNode

qs = YourModel.objects.filter(column=1).all()
qs.query.where = WhereNode() # resets current filters
qs.all() # now you can apply new filters

很难理解您想要做什么,但也许您正在寻找与过滤器相反的排除?我有一个包含许多过滤器的queryset,我想在获取对象之前列出它们并删除其中的一些过滤器。排除方法不能“禁用”查询集上的过滤器我是法国人,也许我不清楚很难理解你想做什么,但也许你在寻找与过滤器相反的排除?我有一个包含许多过滤器的queryset,我想在获取对象之前列出它们并删除其中的一些过滤器。排除方法不能“禁用”查询集上的过滤器。我是法国人,也许我不清楚。很好的文档化回复,谢谢。现在听起来很清楚,但我同意这一点,但肯定不可取:很好的书面答复,非常多。现在听起来很清楚,但肯定不可取我同意: