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

chr*_*e31 0 python django

此功能用于我列出搜索结果的视图中.在我的搜索表单中,我有一些ModelChoiceFields可以通过外键进行搜索.平时的工作流程是指把我们当前的搜索更加精确,所以禁用了很多不相关的结果,我想删除,如果没有其他的搜索参数改变这将返回任何结果条目.

我正在使用对象查询集来限制某些下拉列表中的命题.我使用这些下拉列表来过滤外键我的对象列表.

我的filter函数参数现在是一个Objects查询集:

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()
Run Code Online (Sandbox Code Playgroud)

我的问题是如何从现有的query_set中删除'where close'.在这里,我想从my_objects_queryset中删除哪里关闭哪个过滤器thing = ForeignKey(models.Thing)

可能吗?

类似于列出我们的查询集的所有过滤器并在运行中编辑/删除它们的方法.

Sha*_*hin 6

简短回答:

不,你不能这样做.

答案很长:

从理论上讲,它有可能(在某种程度上),但肯定不可取.

(我还没有完全研究过django源代码,所以接下来是简单地爬上调用树的结果.)

查看QuerySet源代码,filter()exclude()返回查询集本身的克隆,并添加新的规则(使用clone.query.add_q()).

clone.query是一个表示SQL查询对象,add_q()方法添加的新规则clone.query.where实际上是树的根节点.

如何将新节点添加到树中取决于规则是与a AND还是OR子句连接.这很重要,因为它会影响生成的最终SQL查询的正确性.

因此,要列出分配给查询集的过滤器,"简单"需要了解queryset.query.where树的表示方式(请参阅参考资料django.utils.tree).

困难的一点当然是删除过滤器,这样它不会影响剩余的规则.我将不提供解决方案,因为无法保证实施不会因此而使解决方案无效.我怀疑这是可能的,但它闻起来只是出于学术兴趣,或根本没有.


cai*_*aio 6

有人在这里乱砍.

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

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
Run Code Online (Sandbox Code Playgroud)