2011-01-14 2 views
13

У меня есть сторонняя функция, которая дает мне отфильтрованный запрос (например, записи с «valid» = True), но я хочу удалить конкретное условие (например, чтобы иметь все записи, оба действительны и недействительны).Django: удалить условие фильтра из запроса

Есть ли способ удалить условие фильтра для уже отфильтрованного запроса?

E.g.

only_valid = MyModel.objects.filter(valid=True) 
all_records = only_valid.**remove_filter**('valid') 

(я знаю, что было бы лучше, чтобы определить 'all_records' до 'only_valid', но это всего лишь пример ...)

+0

Можете ли вы показать пример кода, пожалуйста? –

ответ

4

the docs От:

Каждый раз вы уточняете QuerySet, вы получаете совершенно новый QuerySet, который никак не связан с предыдущим QuerySet. Каждое уточнение создает отдельный и отличный QuerySet, который может быть сохранен, использован и повторно использован.

У меня есть сомнения, поэтому есть стандартный способ сделать это. Вы могли бы dig into the code, см., Что filter() делает и попробовал. Если это не помогает, я полагаю, вам не повезло, и вам нужно перестроить запрос самостоятельно.

10

Хотя официального способа сделать это с использованием обозначения фильтра, вы можете легко сделать это с помощью Q -notation. Например, если вы убедитесь, что функция третьей частей возвращает объект Q, а не фильтрованного QuerySet, вы можете сделать следующее:

q = ThirdParty() 
q = q | Q(valid=False) 

И будут объединены в результате условия SQL с помощью оператора ИЛИ.

+0

Вам понадобится доступ к стороннему коду, но да, это хорошее решение. +1 – Boldewyn

1

Вот что я сделал в подобном случае.

all_records = MyModel.objects.all() 
only_valid = MyModel.objects.filter(valid=True) 
only_valid.original = all_records 

... 

all_records = only_valid.original 

Очевидно, что это очищает любые другие фильтры, поэтому это не будет правильным для каждого случая.

0

Спасибо, что заставило меня проверить исходный код Boldewyn. Так, кажется, есть новый метод прямо под фильтром() с теми же параметрами, ... называется exclude() (по фиксации мини-хэш ef6c680, когда она теряет номер строки)

Возвращает новый экземпляр QuerySet с NOT (args) ANDed к существующему набору.

Таким образом, чтобы ответить на исходный вопрос:

only_valid = MyModel.objects.filter(valid=True) 
filtered_results = only_valid.exclude(the_condition_to_remove=True) 
+0

'exclude' просто добавляет еще один фильтр, сохраняя существующие. Он не восстанавливает полный набор запросов. – Don

+0

О, я вижу! Тогда я неправильно понял этот вопрос. Спасибо, что освободил это :) – iddy

Смежные вопросы