Как редактировать список фильтров набора запросов - PullRequest
0 голосов
/ 07 марта 2011

Эта функция используется при просмотре списка результатов поиска. В моей форме поиска у меня есть несколько ModelChoiceFields для поиска по внешним ключам. Обычный рабочий процесс означает, что наш текущий поиск становится все более и более точным, поэтому, чтобы отключить множество не относящихся к делу результатов, я пытаюсь удалить записи, которые не дали бы никакого результата, если другие параметры поиска не изменятся.

Я использую объектный набор запросов для ограничения предложений в некоторых выпадающих списках. Я использую эти выпадающие списки для фильтрации по внешнему ключу моего списка объектов.

Мой аргумент функции для фильтрации - это набор запросов 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()

Моя проблема заключается в том, как удалить «где закрыть» из существующего набора запросов. Здесь я хочу удалить из my_objects_queryset, где закрывается, какой фильтр на thing = ForeignKey(models.Thing)

Возможно ли это?

Что-то вроде способа перечислить все фильтры нашего набора запросов и редактировать / удалять их на лету.

Ответы [ 2 ]

6 голосов
/ 06 мая 2011

Некоторые взломы здесь.

Вы можете обойти это, "сбросив" текущие фильтры, как показано ниже:

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
6 голосов
/ 07 марта 2011

Краткий ответ:

Нет, вы не можете сделать это.

Длинный ответ:

Теоретически, это может быть возможно (до некоторой степени в любом случае), но определенно не рекомендуется .

(Я не полностью изучил источник django, так что последующее является результатом простого подъема по дереву вызовов.)

Просмотр источника для QuerySet , filter() и exclude() возвращают клон самого набора запросов с новым добавленным правилом (с использованием clone.query.add_q()).

clone.query - это объект , представляющий SQL-запрос , тогда как метод add_q () добавляет новое правило в clone.query.where, который по сути является корневым узел дерева .

Способ добавления нового узла в дерево зависит от того, должно ли правило быть связано с предложением AND или OR. Это важно, поскольку оно влияет на правильность окончательного SQL-запроса, который генерируется .

Итак, чтобы вывести список фильтров, назначенных набору запросов, один "просто" должен понять, как представляется дерево queryset.query.where (см. django.utils.tree).

Сложным является, конечно, удаление фильтров, которые не влияют на остальные правила. Я воздержусь от предложения решения, поскольку нет никакой гарантии, что реализация не изменится, и это сделает решение недействительным. Я подозреваю, что это возможно, но пахнет чем-то, что должно быть сделано только из академического интереса, или не совсем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...