Подтвердить что ты не робот

Фильтр Django против исключения

Есть ли разница между фильтром и исключить в 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)

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

4b9b3361

Ответ 1

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

Ответ 2

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

Здесь:

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

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

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

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

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

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

Ответ 3

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