Существуют огромные различия между .get(..)
и .filter(..)
.Вкратце: .get(..)
получает один экземпляр модели, который удовлетворяет заданным условиям, тогда как .filter(..)
фильтрует набор запросов и создает набор запросов, который концептуально содержит экземпляр модели s (!), Который удовлетворяет заданным условиям.
Django's .get(..)
.get
означает, что вы стремитесь получить ровно один экземпляр.Так что это означает, что если вы напишите:
Model.objects.get(..)
, результатом будет Model
экземпляр (если есть такой экземпляр).В результате мы можем получить атрибуты (например, .professors
и т. Д.) От этого единственного объекта.У нас есть гарантии, если вызов будет успешным, что: (1) не существует нескольких объектов, для которых выполняются критерии фильтра;и (2) существует по меньшей мере один элемент, для которого выполняются критерии фильтра.Таким образом, на выходе получается всегда экземпляр модели, а не None
или QuerySet
.
Функция .get(..)
оценивается с нетерпением : мы немедленно выполняемзапрос к базе данных.Если база данных не возвращает записей или двух или более, исключения Model.DoesNotExist
и MultipleObjectsReturned
соответственно повышаются.
Примечание : поскольку .get(..)
действует активно, добавление фильтров и т. Д. Справа от .get(..)
не имеет смысла (хорошо, если вы не определили функцию filter
наэтот случай, но это тоже не очень хорошая идея).Однако вы можете использовать такие функции, как .values()
, values_list
, prefetch_related
и т. Д. С левой стороны, чтобы изменить тип вывода (и выполнить предварительную выборку определенных частей).Например:
Student.objects<b>.values()</b>.get(name='Mike')
приведет к появлению словаря, содержащего значения этого экземпляра.
Фильтр Django .filter(..)
с другой стороны фильтры набор запросов.Это означает, что возможно после того, как мы отфильтруем, набор запросов больше не будет содержать никаких экземпляров (если фильтр слишком ограничительный) или еще двух (если фильтр слишком слаб, чтобы закрепить одну запись).
Джанго не оценивает такие .filter(..)
с нетерпением .Это означает, что по умолчанию Django не сделает запрос к базе данных для получения записей.Только если вы вызываете, например, len(..)
для полученного набора запросов или выполняете итерацию по нему, Django сначала выполнит запрос к базе данных, а затем обработает соответствующий результат.
Поскольку результат .filter(..)
является другимQuerySet
, мы можем объединить операции вместе.Например, мы можем вызвать дополнительные .filter(..)
или .exclude(..)
, values_list(..)
или любую другую функцию, поддерживаемую QuerySet
.
Поскольку результат не является экземпляром модели, мы не можем вызватьатрибуты экземпляра модели.Каким должен быть результат Student.objects.filter(..).name
, если ни один студент не соответствует критериям?Или что, если существует несколько Student
с, соответствующих данному ограничению?
Однако мы можем получить список Professor
с, которые обучают одного или нескольких Student
с именем 'Mike'
с:
# professors with a student called Mike
Professors.objects.filter(students__name="Mike")
Фильтр никогда не вызовет исключение Model.DoesNotExist
или MultipleObjectsReturned
, посколькувполне допустимо работать с пустыми QuerySet
с или QuerySet
с несколькими элементами.