Фильтр Django против исключения - PullRequest
26 голосов
/ 11 марта 2010

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

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)

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

Ответы [ 3 ]

22 голосов
/ 11 марта 2010

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

18 голосов
/ 11 марта 2010

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

Здесь:

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

Вы выбираете записи, в которых поле user не имеет значение null, а modelField имеет значение x

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

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

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

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

12 голосов
/ 11 марта 2010

Это зависит от того, чего вы хотите достичь. С логическими значениями легко переключаться между .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(), но для других значений это может быть более сложным.

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