Referencia de la API de búsqueda

Este documento tiene las referencias de la API de lookups, la API de Django para construir la cláusula WHERE de una consulta de base de datos. Para aprender a utilizar lookups, vea Haciendo consultas; para aprender a crear nuevas lookups, vea Cómo escribir consultas personalizadas.

La API de lookups tiene dos componentes: una clase RegisterLookupMixin que registra lookups, y la API de Expresión de Consultas, un conjunto de métodos que una clase debe implementar para ser registrable como lookup.

Django tiene dos clases base que siguen la API de expresión de consultas y desde donde se derivan todas las lookups de Django:

  • Lookup: para buscar un campo (por ejemplo, el exact de field_name__exact)

  • Transform: para transformar un campo

Una expresión de lookup consta de tres partes:

  • Parte de campos (por ejemplo, Book.objects.filter(author__best_friends__first_name...);

  • Parte de transformaciones (puede omitirse) (por ejemplo, __lower__first3chars__reversed);

  • Una lookup (por ejemplo, __icontains) que, si se omite, tiene como valor por defecto __exact.

API de registro

Django utiliza la clase RegisterLookupMixin para dar a una clase la interfaz para registrar lookups en ella o sus instancias. Los dos ejemplos más destacados son Field, la clase base de todos los campos de modelo, y Transform, la clase base de todos los transformaciones de Django.

class lookups.RegisterLookupMixin

Una mezcla que implementa la API de búsqueda en una clase.

classmethod register_lookup(lookup, lookup_name=None)

Registra un nuevo lookup en la clase o instancia de la clase. Por ejemplo:

DateField.register_lookup(YearExact)
User._meta.get_field("date_joined").register_lookup(MonthExact)

registrará el lookup YearExact en DateField y el lookup MonthExact en User.date_joined (puedes utilizar API de acceso a campos para recuperar una instancia de campo individual). Sustituye un lookup que ya existe con el mismo nombre. Los lookups registrados en instancias de campos tienen prioridad sobre los lookups registrados en clases. lookup_name se utilizará para este lookup si se proporciona, de lo contrario lookup.lookup_name se utilizará.

get_lookup(lookup_name)

Devuelve la clase Lookup llamada lookup_name registrada en la clase o instancia de la clase dependiendo de quién la llame. La implementación predeterminada busca recursivamente en todas las clases padre y verifica si alguna tiene un lookup registrado con el nombre lookup_name, devolviendo la primera coincidencia. Los lookups de instancias sobrescribirían cualquier lookup de clase con el mismo lookup_name.

get_lookups()

Devuelve un diccionario de cada nombre de lookup registrado en la clase o instancia de la clase mapeado a la clase Lookup.

get_transform(transform_name)

Devuelve una clase Transform llamada transform_name registrada en la clase o instancia de la clase. La implementación predeterminada busca recursivamente en todas las clases padre para verificar si alguna tiene la transform registrada con el nombre transform_name, devolviendo la primera coincidencia.

Para que una clase sea un lookup, debe seguir la API de expresión de consulta. Lookup y Transform siguen naturalmente esta API.

La API de expresión de consulta

La API de expresión de consulta es un conjunto común de métodos que las clases definen para ser utilizables en expresiones de consulta para traducirse a expresiones SQL. Las referencias directas de campos, los agregados y Transform son ejemplos que siguen esta API. Una clase se dice que sigue la API de expresión de consulta cuando implementa los siguientes métodos:

as_sql(compiler, connection)

Genera el fragmento SQL para la expresión. Devuelve una tupla (sql, params), donde sql es la cadena de SQL y params es la lista o tupla de parámetros de consulta. El compiler es un objeto SQLCompiler, que tiene un método compile() que se puede utilizar para compilar otras expresiones. La connection es la conexión utilizada para ejecutar la consulta.

Llamar a expression.as_sql() suele ser incorrecto - en su lugar, debe usarse compiler.compile(expression). El método compiler.compile() se encargará de llamar a los métodos específicos del proveedor de la expresión.

Pueden definirse argumentos de palabra clave personalizados en este método si es probable que los métodos o subclases as_vendorname() necesiten suministrar datos para sobreescribir la generación de la cadena SQL. Consulte el ejemplo de uso en Func.as_sql().

as_vendorname(compiler, connection)

Funciona como el método as_sql(). Cuando una expresión se compila con compiler.compile(), Django intentará llamar a as_vendorname(), donde vendorname es el nombre del proveedor utilizado para ejecutar la consulta. El vendorname es uno de postgresql, oracle, sqlite o mysql para los backends integrados de Django.

get_lookup(lookup_name)

Deben devolverse las consultas nombradas lookup_name. Por ejemplo, devolviendo self.output_field.get_lookup(lookup_name).

get_transform(transform_name)

Deben devolverse las transformaciones nombradas transform_name. Por ejemplo, devolviendo self.output_field.get_transform(transform_name).

output_field

Define el tipo de clase devuelto por el método get_lookup(). Debe ser una instancia de Field.

Referencia a la transformación

class Transform[fuente]

Una Transform es una clase genérica para implementar transformaciones de campos. Un ejemplo destacado es __year que transforma un campo DateField en un campo IntegerField.

La notación para utilizar una Transform en una expresión de consulta de lookup es <expresión>__<transformación> (por ejemplo, date__year).

Esta es la traducción de los textos:

bilateral

Un valor booleano indicando si esta transformación debe aplicarse a ambos lhs y rhs. Las transformaciones bilaterales se aplicarán a rhs en el mismo orden en que aparecen en la expresión de búsqueda. Por defecto está configurado en False. Para ver un ejemplo de uso, consulte Cómo escribir consultas personalizadas.

lhs[fuente]

El lado izquierdo - lo que se está transformando. Debe seguir la API de Expresión de Consulta.

lookup_name

El nombre del lookup, utilizado para identificarlo al parsear expresiones de consulta. No puede contener la cadena "__".

output_field

Define la clase a la que se produce esta transformación. Debe ser una instancia de Field. Por defecto es el mismo que su lhs.output_field.

Referencia de Lookup

class Lookup[fuente]

Un Lookup es una clase genérica para implementar consultas. Una consulta es una expresión de consulta con un lado izquierdo, lhs; un lado derecho, rhs; y un lookup_name que se utiliza para producir una comparación booleana entre lhs y rhs como lhs en rhs o lhs > rhs.

La notación primaria para utilizar un lookup en una expresión es <lhs>__<lookup_name>=<rhs>. Los lookups también se pueden utilizar directamente en los filtros de QuerySet:

Book.objects.filter(LessThan(F("word_count"), 7500))

…o anotaciones:

Book.objects.annotate(is_short_story=LessThan(F("word_count"), 7500))
lhs

El lado izquierdo - lo que se está buscando. El objeto típicamente sigue la API de Expresión de Consulta. También puede ser un valor plano.

rhs

El lado derecho - lo que lhs se está comparando contra. Puede ser un valor plano, o algo que compila en SQL, típicamente un objeto F() o una QuerySet.

lookup_name

El nombre de esta búsqueda, utilizado para identificarlo al parsear expresiones de consulta. No puede contener la cadena "__".

prepare_rhs

Por defecto es True. Cuando rhs es un valor plano, prepare_rhs determina si debe prepararse para su uso como parámetro en una consulta. Para ello, se llama a lhs.output_field.get_prep_value() si está definido, o se envuelve a rhs en Value() de lo contrario.

process_lhs(compiler, connection, lhs=None)[fuente]

Devuelve una tupla (lhs_string, lhs_params), como devuelta por compiler.compile(lhs). Este método puede sobrescribirse para ajustar cómo se procesa el lhs.

compiler es un objeto SQLCompiler, que debe usarse como compiler.compile(lhs) para compilar lhs. La connection se puede usar para compilar SQL específico del proveedor. Si lhs no es None, utilízalo como el procesado lhs en lugar de self.lhs.

process_rhs(compiler, connection)[fuente]

Se comporta de la misma manera que process_lhs(), para el lado derecho.