# Documentation Django 5.2.8

# API de référence des expressions de recherche

Ce document contient les références d’API des expressions de recherches, l’API Django pour la construction des clauses `WHERE` des requêtes de bases de données. Pour apprendre comment utiliser ces expressions, consultez Création de requêtes. Pour apprendre comment créer de nouvelles expressions, consultez Écriture d’expressions de requêtes personnalisées.

L’API des expressions de recherche possède deux parties : une classe `RegisterLookupMixin` qui inscrit les expressions et l’API des expressions de recherche, un ensemble de méthodes qu’une classe doit implémenter afin d’être inscriptible comme expression de recherche.

Django possède deux classes de base qui respectent l’API d’expression de recherche et à partir desquelles toutes les expressions de recherche fournies par Django sont dérivées :

- `Lookup`: pour rechercher un champ (par ex. la partie `exact` de `nom_champ__exact`)

- `Transform`: pour transformer un champ

Une expression de recherche est formée de trois parties :

- la partie des champs (par ex. `Livre.objects.filter(auteur__meilleurs_amis__prenom...`) ;

- la partie de transformation (peut être omise) (par ex. `__lower__troispremierscars__reversed`) ;

- la partie de recherche (par ex. `__icontains`) qui, si elle est omise, correspond à `__exact`.

## API d’inscription

Django utilise `RegisterLookupMixin` pour donner à une classe l’interface pour inscrire des recherches avec elle-même ou avec ses instances. Les deux exemples majeurs sont `Field`, la classe de base de tous les champs de modèles, et `Transform`, la classe de base de toutes les transformations de Django.

class lookups.RegisterLookupMixin

  Une classe mixin qui implémente l’API de recherche pour une classe.

  classmethod register_lookup(lookup, lookup_name=None)

    Inscrit une nouvelle expression de requête dans la classe ou l’instance de classe. Par exemple

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

    va inscrire la recherche `YearExact` pour `DateField` et la recherche `MonthExact` pour `User.date_joined` (vous pouvez utiliser l”:ref:API d’accès aux champs <model-meta-field-api>` pour récupérer une seule instance de champ). Si une recherche existe déjà avec le même nom, elle sera écrasée. Les expressions de requête inscrites pour des instances de champs ont la priorité sur celles inscrites sur les classes. Le nom utilisé pour cette expression sera `lookup_name`, si indiqué, sinon ce sera `lookup.lookup_name`.

  get_lookup(lookup_name)

    Renvoie la recherche `Lookup` nommée `lookup_name` inscrite dans la classe ou l’instance de classe selon l’origine de l’appel. L’implémentation par défaut cherche récursivement dans toutes les classes parentes et vérifie si l’une d’elles possède une recherche inscrite sous le nom `lookup_name`, et renvoie la première qu’elle rencontre. Des recherches inscrites sur les instances écrasent toute recherche sur la classe ayant le même nom `lookup_name`.

  get_lookups()

    Renvoie un dictionnaire faisant correspondre chaque nom de requête inscrit dans la classe ou instance de classe avec sa classe `Lookup`.

  get_transform(transform_name)

    Renvoie une transformation `Transform` nommée `transform_name`, inscrite dans la classe ou une instance de classe. L’implémentation par défaut cherche récursivement dans toutes les classes parentes et vérifie si l’une d’elles possède une transformation inscrite sous le nom `transform_name`, et renvoie la première qu’elle rencontre.

Pour qu’une classe soit considérée comme une recherche, elle doit suivre l’API d’expression de recherche. `Lookup` et `Transform` suivent naturellement cette API.

## L’API d’expression de recherche

L’API d’expression de recherche est un ensemble commun de méthodes que les classes définissent afin de pouvoir être utilisées dans les expressions de recherche avec la capacité de se traduire en expressions SQL. Les références directes aux champs, les agrégations et les expressions `Transform` sont des exemples qui respectent cette API. On dit d’une classe qu’elle respecte l’API d’expression de recherche lorsqu’elle implémente les méthodes suivantes :

as_sql(compiler, connection)

  Génère le fragment SQL de l’expression. Renvoie un tuple `(sql, params)`, où `sql` est la chaîne SQL et `params` est la liste ou le tuple des paramètres de requête. `compiler` est un objet `SQLCompiler` comportant une méthode `compile()` pouvant être utilisée pour compiler d’autres expressions. `connection` est la connexion utilisée pour exécuter la requête.

  Il n’est normalement pas correct d’appeler `expression.as_sql()`, c’est plutôt `compiler.compile(expression)` qui doit être utilisé. La méthode `compiler.compile()` se charge d’appeler les méthodes spécifiques au fournisseur de base de données pour l’expression donnée.

  Des paramètres nommés personnalisés peuvent être définis pour cette méthode s’il est probable que des méthodes `as_nomfournisseur()` ou des sous-classes pourraient vouloir fournir des données pour surcharger la génération de la chaîne SQL. Voir `Func.as_sql()` pour un exemple d’utilisation.

as_vendorname(compiler, connection)

  Fonctionne comme la méthode `as_sql()`. Lorsqu’une expression est compilée avec `compiler.compile()`, Django essaie d’abord d’appeler `as_nomfournisseur()` où `nomfournisseur` correspond au nom du fournisseur de la base de données utilisée pour exécuter la requête. Pour les moteurs fournis avec Django, `nomfournisseur` peut correspondre à `postgresql`, `oracle`, `sqlite` ou `mysql`.

get_lookup(lookup_name)

  Doit renvoyer la recherche nommée `lookup_name`. Par exemple, en renvoyant `self.output_field.get_lookup(lookup_name)`.

get_transform(transform_name)

  Doit renvoyer la transformation nommée `transform_name`. Par exemple, en renvoyant `self.output_field.get_transform(transform_name)`.

output_field

  Définit le type de classe renvoyée par la méthode `get_lookup()`. Il doit s’agir d’une instance `Field`.

## Référence de `Transform`

class Transform

  `Transform` est une classe générique pour implémenter des transformations de champs. Un exemple typique est `__year` (année) qui transforme un champ `DateField` en champ `IntegerField`.

  La notation utilisée pour placer `Transform` dans une expression de recherche est `<expression>__<transformation>` (par ex. `date__year`).

  This class follows the Query Expression API, which implies that you can use `<expression>__<transform1>__<transform2>`. It’s a specialized Func() expression that only accepts one argument. It can also be used on the right hand side of a filter or directly as an annotation.

  bilateral

    Une valeur booléenne indiquant si cette transformation doit s’appliquer aux deux parties `lhs` et `rhs`. Les transformations bilatérales seront appliquées à `rhs` dans leur ordre d’apparition dans l’expression de requête. Par défaut, cet attribut vaut `False`. Pour des exemples d’utilisation, voir Écriture d’expressions de requêtes personnalisées.

  lhs

    La partie gauche de l’expression, ce qui est transformé. Elle doit respecter l’API d’expression de recherche.

  lookup_name

    Le nom de la transformation, utilisé pour l’identifier lors de l’analyse des expressions de recherche. Il ne peut pas contenir la chaîne `"__"`.

  output_field

    Définit la classe que cette transformation produit. Il doit s’agir d’une instance de `Field`. Par défaut, c’est la même classe que `lhs.output_field`.

## Référence de `Lookup`

class Lookup

  `Lookup` est une classe générique pour implémenter des recherches. Une recherche est une expression de requête avec un côté gauche `lhs`, un côté droit `rhs` et un nom `lookup_name` utilisé pour produire une comparaison booléenne entre `lhs` et `rhs` telle que `lhs in rhs` ou `lhs > rhs`.

  La notation principale pour utiliser une recherche dans une expression est `<lhs>__<nom_recherche>=<rhs>`. Les recherches peuvent également être utilisées directement dans les filtres de `QuerySet`:

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

  ou dans les annotations

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

  lhs

    Le côté gauche, le contenu recherché. L’objet respecte typiquement l’API d’expression de recherche. Cela peut aussi être une simple valeur.

  rhs

    Le côté droit, ce qui est comparé avec `lhs`. Il peut s’agir d’une valeur brute ou de quelque chose qui se compile en SQL, typiquement un objet `F()` ou un `QuerySet`.

  lookup_name

    Le nom de la recherche, utilisé pour l’identifier lors de l’analyse des expressions de recherche. Il ne peut pas contenir la chaîne `"__"`.

  prepare_rhs

    Vaut `True` par défaut. Lorsque `rhs` est une simple valeur, `prepare_rhs` détermine s’il doit être préparé pour une utilisation comme paramètre dans une requête. Dans ce but, `lhs.output_field.get_prep_value()` est appelée si elle est définie, ou sinon `rhs` est enveloppé dans une instance `Value()`.

  process_lhs(compiler, connection, lhs=None)

    Renvoie un tuple `(lhs_string, lhs_params)`, tel que renvoyé par `compiler.compile(lhs)`. Cette méthode peut être surchargée pour affiner le traitement de `lhs`.

    `compiler` est un objet `SQLCompiler` destiné à la compilation de `lhs`, comme avec `compiler.compile(lhs)`. Le paramètre `connection` peut être utilisé pour compiler du SQL selon un fournisseur particulier. Si `lhs` n’est pas `None`, ce paramètre est employé comme `lhs` à la place de `self.lhs`.

  process_rhs(compiler, connection)

    Se comporte de la même manière que `process_lhs()`, mais pour le côté droit.