2010-03-11 2 views
19

Есть ли разница между фильтром и исключить в django? Если у меня естьФильтр Django vs exclude

self.get_query_set().filter(modelField=x) 

, и я хочу добавить еще критерии, есть смысл разница между ними, чтобы следующие две строки кода?

self.get_query_set().filter(user__isnull=False, modelField=x) 

self.get_query_set().filter(modelField=x).exclude(user__isnull=True) 

считается лучшей практикой или они одинаковы как в функции, так и в производительности?

ответ

16

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

+0

спасибо. так что это только вопрос личных предпочтений? Я просто хотел убедиться, что я не собираюсь делать что-то необъяснимо глупое. – Enrico

+2

@ Enrico: Не совсем, это зависит от того, чего вы хотите. См. Мой ответ. Производительность не имеет значения в этом случае, это два метода, которые служат для разных целей. Для генерации SQL в документации говорится о '.exclude()': * Несколько параметров объединяются через AND в базовый оператор SQL, и все это заключено в NOT(). * –

+0

@Felix. Благодарю. Я предполагаю, что мой главный вопрос, который я мог бы сообщить более четко, касался производительности как в джанго, так и в конечном счете в SQL. Из вашего последующего комментария кажется, что он может работать лучше, чем другой, но в основном на основе полученного SQL. Тем не менее, изменение второго оператора в '.exclude (user__isnull = True) .filter (modelField = x)' затем сделает два утверждения более или менее равными. – Enrico

15

В общем исключить - напротив фильтра. В этом случае оба примера работают одинаково.

Здесь:

self.get_query_set().filter(user__isnull=False, modelField=x) 

Вы выбираете записи, которые пользователь поле не равно нулю и modelField имеет значение х

В этом случае:

self.get_query_set().filter(modelField=x).exclude(user__isnull=True) 

Сначала вы выбираете записи, modelField имеет значение x (оба пользователя в null и пользователь не являются нулевыми), то вы исключаете записи, у которых есть поле пользователя null.

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

9

Это зависит от того, чего вы хотите достичь. С булевыми значениями легко переключаться между .exclude() и .filter(), но как насчет, например, если вы хотите получить все статьи, кроме мартовских? Вы можете написать запрос как

Posts.objects.exclude(date__month=3) 

С .filter() было бы (но на самом деле работает, я не уверен, является ли это):

Posts.objects.filter(date__month__in=[1,2,4,5,6,7,8,9,10,11,12]) 

или вы должны использовать Q объект.

В качестве названия функции уже предлагается .exclude() Используется для Исключить Наборы данных из списка результатов. Для булевых значений вы можете легко инвертировать это значение и использовать вместо него .filter(), но для других значений это может быть более сложным.

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