Справочник 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(для получения экземпляра отдельного поля можно использовать 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и возвращает первое совпадение.
-
Чтобы класс считался оператором поиска, он должен соответствовать API выражений запросов. Классы Lookup и Transform изначально соответствуют этому API.
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— имя поставщика используемой для выполнения запроса серверной части. Для встроенных серверных частей Djangovendornameпринимает одно из значений:postgresql,oracle,sqliteилиmysql.
-
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).
-
output_field -
Определяет тип класса, возвращаемого методом
get_lookup(). Должен быть экземпляромField.
Transform: справочник
-
class Transform[исходный код] -
Transform— это универсальный класс для реализации преобразований полей. Известный пример —__year, преобразующийDateFieldвIntegerField.В выражении поиска
Transformиспользуется запись<expression>__<transformation>(например,date__year).Этот класс соответствует API выражений запросов, а значит, можно использовать
<expression>__<transform1>__<transform2>. Это специализированное выражение Func(), принимающее только один аргумент. Его также можно использовать в правой части фильтра или непосредственно как аннотацию.-
bilateral -
Логическое значение, указывающее, следует ли применять это преобразование к обеим частям:
lhsиrhs. Двусторонние преобразования применяются кrhsв том же порядке, в котором они указаны в выражении поиска. По умолчанию установлено значениеFalse. Пример использования см. в разделе Как писать пользовательские операторы поиска.
-
lhs[исходный код] -
Левая часть — то, что преобразуется. Она должна соответствовать API выражений запросов.
-
lookup_name -
Имя оператора поиска, используемое для его идентификации при разборе выражений запросов. Оно не может содержать строку
"__".
-
output_field -
Определяет класс, к которому относится результат этого преобразования. Должен быть экземпляром
Field. По умолчанию совпадает сlhs.output_field.
-
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 -
Левая часть — то, для чего выполняется поиск. Обычно этот объект соответствует 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().
-
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/6.0/ref/models/lookups/