Справочник по API поиска¶
Этот документ содержит ссылки на API для поиска, API Django для построения WHERE
запроса к базе данных. Чтобы узнать, как использовать поиски, смотрите Создание запросов; чтобы узнать, как создавать новые поиски, смотрите Как писать пользовательские поисковые запросы.
API поиска имеет два компонента: RegisterLookupMixin
, который регистрирует поиск, и API выражения запроса, набор методов, которые класс должен реализовать, чтобы быть зарегистрирированным как поиск.
У Django есть два базовых класса, которые следуют API-интерфейсу выражения запроса и откуда берутся все встроенные поиски Django:
Выражение поиска состоит из трех частей:
- Часть полей (например,
Book.objects.filter(author__best_friends__first_name...
); - Преобразуемая часть (может быть опущена) (например,
__lower__first3chars__reversed
); - Поиск (например,
__icontains
), который, если не указан, по умолчанию равен__exact
.
API регистрации¶
Django использует RegisterLookupMixin
для предоставления классу интерфейса для регистрации поиска на самом себе или своих экземплярах. Два ярких примера - Field
, базовый класс всех полей модели, и Transform
, базовый класс всех трансформаций Django.
-
class
lookups.
RegisterLookupMixin
¶ Миксин, который реализует API поиска в классе.
-
classmethod
register_lookup
(lookup, lookup_name=None)¶ Регистрирует новый поиск в классе или экземпляре класса. Например:
DateField.register_lookup(YearExact) User._meta.get_field("date_joined").register_lookup(MonthExact)
зарегистрирует
YearExact
поиск поDateField
иMonthExact
поиск поUser.date_joined
(для получения экземпляра одного поля можно использовать Field Access API). Он переопределяет уже существующий поиск с тем же именем. Поиски, зарегистрированные на экземплярах полей, имеют приоритет над поисками, зарегистрированными на классах. Для данного поиска будет использовано значениеlookup_name
, если оно указано, в противном случае будет использовано значениеlookup.lookup_name
.
-
get_lookup
(lookup_name)¶ Возвращает
Lookup
с именемlookup_name
, зарегистрированный в классе или экземпляре класса, в зависимости от того, что его вызывает. Реализация по умолчанию рекурсивно просматривает все родительские классы и проверяет, есть ли в каком-либо из них зарегистрированный поиск с именемlookup_name
, возвращая первое совпадение. Поиск экземпляра будет переопределять поиск класса с тем же именемlookup_name
.
-
get_lookups
()¶ Возвращает словарь каждого имени поиска, зарегистрированного в классе или экземпляре класса, сопоставленного с классом
Lookup
.
-
get_transform
(transform_name)¶ Возвращает
Transform
с именемtransform_name
, зарегистрированным в классе или экземпляре класса. Реализация по умолчанию рекурсивно просматривает все родительские классы на предмет наличия в них зарегистрированного преобразования с именемtransform_name
, возвращая первое совпадение.
-
classmethod
Чтобы класс был поиском, он должен следовать API выражения запроса. Lookup
и Transform
естественно следуют этому API.
Добавлена поддержка регистрации поиска на экземплярах Field
.
API выражения запроса¶
API выражений запросов - это общий набор методов, классы которых определяют для использования в выражениях запросов для преобразования себя в выражения SQL. Прямые ссылки на поля, агрегаты и Transform
являются примерами, которые следуют этому API. Говорят, что класс следует API-интерфейсу выражения запроса, когда он реализует следующие методы:
-
as_sql
(compiler, connection)¶ Создает фрагмент SQL для выражения. Возвращает кортеж
(sql, params)
, гдеsql
- строка SQL, аparams
- список или кортеж параметров запроса.compiler
- это объектSQLCompiler
, который имеет методcompile()
, который можно использовать для компиляции других выражений.connection
- это соединение, используемое для выполнения запроса.Вызов
expression.as_sql()
обычно некорректен - вместо этого следует использоватьcompiler.compile(expression)
. Методcompiler.compile()
позаботится о вызове специфичных для поставщика методов выражения.Пользовательские аргументы ключевых слов могут быть определены в этом методе, если существует вероятность, что методы или подклассы
as_vendorname()
должны будут предоставить данные для переопределения генерации строки SQL. СмотритеFunc.as_sql()
для примера использования.
-
as_vendorname
(compiler, connection)¶ Работает как
as_sql()
метод. Когда выражение компилируется с помощьюcompiler.compile()
, Django сначала попытается вызватьas_vendorname()
, гдеvendorname
- это имя поставщика серверной части, используемой для выполнения запроса.Vendorname
является одним изpostgresql
,oracle
,sqlite
илиmysql
для встроенных бэкэндов Django.
-
get_lookup
(lookup_name)¶ Должен вернуть поиск с именем
lookup_name
. Например, возвращаяself.output_field.get_lookup(lookup_name)
.
-
get_transform
(transform_name)¶ Должен вернуть поиск с именем
transform_name
. Например, возвращаяself.output_field.get_transform(transform_name)
.
Справочник по Transform
¶
-
class
Transform
[исходный код]¶ Transform
- это универсальный класс для реализации преобразований поля. Ярким примером является__year
, который преобразуетDateField
вIntegerField
.Обозначение для использования
Transform
в поисковом выражении:<expression>__<transformation>
(например,date__year
).Этот класс следует за API запроса, что подразумевает, что вы можете использовать
<expression>__<transform1>__<transform2>
. Это специализированное Func () выражение, которое принимает только один аргумент. Его также можно использовать с правой стороны фильтра или непосредственно в качестве аннотации.-
bilateral
¶ Логическое значение, указывающее, должно ли это преобразование применяться как к
lhs
, так и кrhs
. Двусторонние преобразования будут применены кrhs
в том же порядке, в котором они отображаются в поисковом выражении. По умолчанию установлено значениеFalse
. Для примера использования смотрите howto/custom-lookups.
-
lhs
¶ Левая сторона - что трансформируется. Она должна следовать API запроса.
-
lookup_name
¶ Имя поиска, используемое для его идентификации при разборе выражений запроса. Он не может содержать строку
"__"
.
-
Справочник по Lookup
¶
-
class
Lookup
[исходный код]¶ Lookup
- это универсальный класс для реализации поиска. Поиск - это выражение запроса с левой стороныlhs
; правой стороныrhs
; иlookup_name
, которое используется для получения логического сравнения междуlhs
иrhs
, такого какlhs in rhs
илиlhs > rhs
.Основной нотацией для использования поиска в выражении является
<lhs>__<lookup_name>=<rhs>
. Поиск можно также использовать непосредственно в фильтрахQuerySet
:Book.objects.filter(LessThan(F("word_count"), 7500))
…или аннотации:
Book.objects.annotate(is_short_story=LessThan(F("word_count"), 7500))
-
lhs
¶ Левая часть - то, что ищется. Объект обычно следует за Query Expression API. Это может быть и простое значение.
-
rhs
¶ Правая часть - с чем сравнивается
lhs
. Это может быть простое значение или что-то, что компилируется в SQL, обычно это объектF()
илиQuerySet
.
-
lookup_name
¶ Имя этого поиска, используется для его идентификации при разборе выражений запроса. Он не может содержать строку
"__"
.
-
prepare_rhs
¶ По умолчанию имеет значение
True
. Когдаrhs
является простым значением,prepare_rhs
определяет, следует ли его подготовить для использования в качестве параметра в запросе. Для этого вызываетсяlhs.output_field.get_prep_value()
, если оно определено, илиrhs
оборачивается вValue()
в противном случае.
-
process_lhs
(compiler, connection, lhs=None)[исходный код]¶ Возвращает кортеж
(lhs_string, lhs_params)
, как возвращеноcompiler.compile(lhs)
. Этот метод может быть переопределен для настройки обработкиlhs
.compiler
- это объектSQLCompiler
, который используется какcompiler.compile(lhs)
для компиляцииlhs
.connection
может использоваться для компиляции специфичного для поставщика SQL. Еслиlhs
неNone
, используйте его как обработанныйlhs
вместоself.lhs
.
-
process_rhs
(compiler, connection)[исходный код]¶ Ведет себя так же, как
process_lhs()
, для правой части.
-