{"title":"Expressions de requête","version":"1.11","locale":"fr","docname":"ref/models/expressions","url":"/fr/1.11/ref/models/expressions/","canonical":"https://djangodocs.dev/fr/1.11/ref/models/expressions/","summary":"Les expressions de requête décrivent une valeur ou un calcul pouvant faire partie d’une mise à jour, d’une création, d’un filtre, d’un tri, d’une annotation ou…","html":"<h1>Expressions de requête<a class=\"heading-anchor\" href=\"#query-expressions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Les expressions de requête décrivent une valeur ou un calcul pouvant faire partie d’une mise à jour, d’une création, d’un filtre, d’un tri, d’une annotation ou d’une agrégation. Il existe un certain nombre d’expressions intégrées (documentées ci-dessous) pouvant aider à construire des requêtes. Les expressions peuvent être combinées, ou même imbriquées dans certains cas, afin de former des calculs plus complexes.</p>\n<section id=\"supported-arithmetic\">\n<h2>Arithmétique prise en charge<a class=\"heading-anchor\" href=\"#supported-arithmetic\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Django prend en charge l’addition, la soustraction, la multiplication, la division, l’arithmétique modulo ainsi que l’opérateur de puissance pour les expressions de requête, à l’aide de constantes Python, de variables et même d’autres expressions.</p>\n</section>\n<section id=\"some-examples\">\n<h2>Quelques exemples<a class=\"heading-anchor\" href=\"#some-examples\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">F</span><span class=\"p\">,</span> <span class=\"n\">Count</span><span class=\"p\">,</span> <span class=\"n\">Value</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models.functions</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Length</span><span class=\"p\">,</span> <span class=\"n\">Upper</span>\n\n<span class=\"c1\"># Find companies that have more employees than chairs.</span>\n<span class=\"n\">Company</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">num_employees__gt</span><span class=\"o\">=</span><span class=\"n\">F</span><span class=\"p\">(</span><span class=\"s1\">&#39;num_chairs&#39;</span><span class=\"p\">))</span>\n\n<span class=\"c1\"># Find companies that have at least twice as many employees</span>\n<span class=\"c1\"># as chairs. Both the querysets below are equivalent.</span>\n<span class=\"n\">Company</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">num_employees__gt</span><span class=\"o\">=</span><span class=\"n\">F</span><span class=\"p\">(</span><span class=\"s1\">&#39;num_chairs&#39;</span><span class=\"p\">)</span> <span class=\"o\">*</span> <span class=\"mi\">2</span><span class=\"p\">)</span>\n<span class=\"n\">Company</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span>\n    <span class=\"n\">num_employees__gt</span><span class=\"o\">=</span><span class=\"n\">F</span><span class=\"p\">(</span><span class=\"s1\">&#39;num_chairs&#39;</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"n\">F</span><span class=\"p\">(</span><span class=\"s1\">&#39;num_chairs&#39;</span><span class=\"p\">))</span>\n\n<span class=\"c1\"># How many chairs are needed for each company to seat all employees?</span>\n<span class=\"o\">&gt;&gt;&gt;</span> <span class=\"n\">company</span> <span class=\"o\">=</span> <span class=\"n\">Company</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span>\n<span class=\"o\">...</span>    <span class=\"n\">num_employees__gt</span><span class=\"o\">=</span><span class=\"n\">F</span><span class=\"p\">(</span><span class=\"s1\">&#39;num_chairs&#39;</span><span class=\"p\">))</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span>\n<span class=\"o\">...</span>    <span class=\"n\">chairs_needed</span><span class=\"o\">=</span><span class=\"n\">F</span><span class=\"p\">(</span><span class=\"s1\">&#39;num_employees&#39;</span><span class=\"p\">)</span> <span class=\"o\">-</span> <span class=\"n\">F</span><span class=\"p\">(</span><span class=\"s1\">&#39;num_chairs&#39;</span><span class=\"p\">))</span><span class=\"o\">.</span><span class=\"n\">first</span><span class=\"p\">()</span>\n<span class=\"o\">&gt;&gt;&gt;</span> <span class=\"n\">company</span><span class=\"o\">.</span><span class=\"n\">num_employees</span>\n<span class=\"mi\">120</span>\n<span class=\"o\">&gt;&gt;&gt;</span> <span class=\"n\">company</span><span class=\"o\">.</span><span class=\"n\">num_chairs</span>\n<span class=\"mi\">50</span>\n<span class=\"o\">&gt;&gt;&gt;</span> <span class=\"n\">company</span><span class=\"o\">.</span><span class=\"n\">chairs_needed</span>\n<span class=\"mi\">70</span>\n\n<span class=\"c1\"># Create a new company using expressions.</span>\n<span class=\"o\">&gt;&gt;&gt;</span> <span class=\"n\">company</span> <span class=\"o\">=</span> <span class=\"n\">Company</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">create</span><span class=\"p\">(</span><span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;Google&#39;</span><span class=\"p\">,</span> <span class=\"n\">ticker</span><span class=\"o\">=</span><span class=\"n\">Upper</span><span class=\"p\">(</span><span class=\"n\">Value</span><span class=\"p\">(</span><span class=\"s1\">&#39;goog&#39;</span><span class=\"p\">)))</span>\n<span class=\"c1\"># Be sure to refresh it if you need to access the field.</span>\n<span class=\"o\">&gt;&gt;&gt;</span> <span class=\"n\">company</span><span class=\"o\">.</span><span class=\"n\">refresh_from_db</span><span class=\"p\">()</span>\n<span class=\"o\">&gt;&gt;&gt;</span> <span class=\"n\">company</span><span class=\"o\">.</span><span class=\"n\">ticker</span>\n<span class=\"s1\">&#39;GOOG&#39;</span>\n\n<span class=\"c1\"># Annotate models with an aggregated value. Both forms</span>\n<span class=\"c1\"># below are equivalent.</span>\n<span class=\"n\">Company</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span><span class=\"n\">num_products</span><span class=\"o\">=</span><span class=\"n\">Count</span><span class=\"p\">(</span><span class=\"s1\">&#39;products&#39;</span><span class=\"p\">))</span>\n<span class=\"n\">Company</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span><span class=\"n\">num_products</span><span class=\"o\">=</span><span class=\"n\">Count</span><span class=\"p\">(</span><span class=\"n\">F</span><span class=\"p\">(</span><span class=\"s1\">&#39;products&#39;</span><span class=\"p\">)))</span>\n\n<span class=\"c1\"># Aggregates can contain complex computations also</span>\n<span class=\"n\">Company</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span><span class=\"n\">num_offerings</span><span class=\"o\">=</span><span class=\"n\">Count</span><span class=\"p\">(</span><span class=\"n\">F</span><span class=\"p\">(</span><span class=\"s1\">&#39;products&#39;</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"n\">F</span><span class=\"p\">(</span><span class=\"s1\">&#39;services&#39;</span><span class=\"p\">)))</span>\n\n<span class=\"c1\"># Expressions can also be used in order_by()</span>\n<span class=\"n\">Company</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">order_by</span><span class=\"p\">(</span><span class=\"n\">Length</span><span class=\"p\">(</span><span class=\"s1\">&#39;name&#39;</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">asc</span><span class=\"p\">())</span>\n<span class=\"n\">Company</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">order_by</span><span class=\"p\">(</span><span class=\"n\">Length</span><span class=\"p\">(</span><span class=\"s1\">&#39;name&#39;</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">desc</span><span class=\"p\">())</span>\n</code></pre></div>\n</section>\n<section id=\"built-in-expressions\">\n<h2>Expressions intégrées<a class=\"heading-anchor\" href=\"#built-in-expressions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>Ces expressions sont définies dans <code class=\"docutils literal notranslate\"><span class=\"pre\">django.db.models.expressions</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">django.db.models.aggregates</span></code>, mais par commodité elles sont disponibles et habituellement importées à partir de <a class=\"reference internal\" href=\"/fr/1.11/topics/db/models/#module-django.db.models\" title=\"django.db.models\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">django.db.models</span></code></a>.</p>\n</aside>\n<section id=\"f-expressions\">\n<h3>Expressions <code class=\"docutils literal notranslate\"><span class=\"pre\">F()</span></code><a class=\"heading-anchor\" href=\"#f-expressions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.F\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">F</span></span><a class=\"heading-anchor\" href=\"#django.db.models.F\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Un objet <code class=\"docutils literal notranslate\"><span class=\"pre\">F()</span></code> représente la valeur d’un champ de modèle ou d’une colonne annotée. Il permet de se référer à des valeurs de champs de modèles et d’effectuer avec elles des opérations en base de données sans avoir à les récupérer préalablement de la base de données vers la mémoire Python.</p>\n<p>Au lieu de cela, Django utilise un objet <code class=\"docutils literal notranslate\"><span class=\"pre\">F()</span></code> pour générer une expression SQL qui décrit l’opération requise au niveau de la base de données.</p>\n<p>Il est plus simple de faire comprendre cela par un exemple. Normalement, on peut faire quelque chose comme ceci :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"c1\"># Tintin filed a news story!</span>\n<span class=\"n\">reporter</span> <span class=\"o\">=</span> <span class=\"n\">Reporters</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;Tintin&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">reporter</span><span class=\"o\">.</span><span class=\"n\">stories_filed</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span>\n<span class=\"n\">reporter</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>Ici, nous avons obtenu en mémoire la valeur de <code class=\"docutils literal notranslate\"><span class=\"pre\">reporter.stories_filed</span></code> à partir de la base de données et nous l’avons manipulée avec des opérateurs Python familiers. Nous avons ensuite enregistré l’objet modifié en base de données. Cependant, nous aurions tout aussi bien pu écrire :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">F</span>\n\n<span class=\"n\">reporter</span> <span class=\"o\">=</span> <span class=\"n\">Reporters</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;Tintin&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">reporter</span><span class=\"o\">.</span><span class=\"n\">stories_filed</span> <span class=\"o\">=</span> <span class=\"n\">F</span><span class=\"p\">(</span><span class=\"s1\">&#39;stories_filed&#39;</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"mi\">1</span>\n<span class=\"n\">reporter</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>Même si <code class=\"docutils literal notranslate\"><span class=\"pre\">reporter.stories_filed</span> <span class=\"pre\">=</span> <span class=\"pre\">F('stories_filed')</span> <span class=\"pre\">+</span> <span class=\"pre\">1</span></code> apparaît comme une attribution normale de valeur à un attribut d’instance en Python, il s’agit en réalité d’une construction SQL décrivant une opération en base de données.</p>\n<p>Lorsque Django rencontre une instance de <code class=\"docutils literal notranslate\"><span class=\"pre\">F()</span></code>, il surcharge les opérateurs Python standards pour créer une expression SQL encapsulée ; dans ce cas, une instruction qui demande à la base de données d’incrémenter le champ de base de données représenté par <code class=\"docutils literal notranslate\"><span class=\"pre\">reporter.stories_filed</span></code>.</p>\n<p>Quelle que soit la valeur que contenait <code class=\"docutils literal notranslate\"><span class=\"pre\">reporter.stories_filed</span></code>, Python n’a jamais besoin de la connaître, car tout se passe en base de données. Tout ce que Python fait à travers la classe <code class=\"docutils literal notranslate\"><span class=\"pre\">F()</span></code> de Django est de créer la syntaxe SQL pour se référer au champ et décrire l’opération.</p>\n<p>Pour accéder à la nouvelle valeur qui a été enregistrée de cette manière, l’objet doit être rechargé :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">reporter</span> <span class=\"o\">=</span> <span class=\"n\">Reporters</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"n\">pk</span><span class=\"o\">=</span><span class=\"n\">reporter</span><span class=\"o\">.</span><span class=\"n\">pk</span><span class=\"p\">)</span>\n<span class=\"c1\"># Or, more succinctly:</span>\n<span class=\"n\">reporter</span><span class=\"o\">.</span><span class=\"n\">refresh_from_db</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>En plus d’être utilisée dans les opérations sur des instances uniques comme ci-dessus, <code class=\"docutils literal notranslate\"><span class=\"pre\">F()</span></code> peut être utilisée sur des jeux <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySets</span></code> d’instances d’objets, avec <code class=\"docutils literal notranslate\"><span class=\"pre\">update()</span></code>. Cela permet de réduire les deux requêtes utilisées ci-dessus, <code class=\"docutils literal notranslate\"><span class=\"pre\">get()</span></code> et <a class=\"reference internal\" href=\"/fr/1.11/ref/models/instances/#django.db.models.Model.save\" title=\"django.db.models.Model.save\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">save()</span></code></a>, à une seule :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">reporter</span> <span class=\"o\">=</span> <span class=\"n\">Reporters</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;Tintin&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">reporter</span><span class=\"o\">.</span><span class=\"n\">update</span><span class=\"p\">(</span><span class=\"n\">stories_filed</span><span class=\"o\">=</span><span class=\"n\">F</span><span class=\"p\">(</span><span class=\"s1\">&#39;stories_filed&#39;</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Nous pouvons aussi utiliser <a class=\"reference internal\" href=\"/fr/1.11/ref/models/querysets/#django.db.models.query.QuerySet.update\" title=\"django.db.models.query.QuerySet.update\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">update()</span></code></a> pour incrémenter la valeur du champ sur plusieurs objets, ce qui peut être beaucoup plus rapide que de récupérer toutes les valeurs en Python depuis la base de données, de les passer en boucle en incrémentant la valeur des champs pour chacun, et de les réenregistrer individuellement dans la base de données :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">Reporter</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">all</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">update</span><span class=\"p\">(</span><span class=\"n\">stories_filed</span><span class=\"o\">=</span><span class=\"n\">F</span><span class=\"p\">(</span><span class=\"s1\">&#39;stories_filed&#39;</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">F()</span></code> peut donc offrir des avantages de performance en :</p>\n<ul class=\"simple\">\n<li><p>faisant travailler la base de données plutôt que le code Python ;</p></li>\n<li><p>réduisant le nombre de requêtes de certaines opérations.</p></li>\n</ul>\n<section id=\"avoiding-race-conditions-using-f\">\n<span id=\"id1\"></span><h4>Prévention des conflits de concurrence avec <code class=\"docutils literal notranslate\"><span class=\"pre\">F()</span></code><a class=\"heading-anchor\" href=\"#avoiding-race-conditions-using-f\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Un autre bénéfice notable de <code class=\"docutils literal notranslate\"><span class=\"pre\">F()</span></code> est que de faire mettre à jour la valeur d’un champ par la base de données plutôt qu’en Python évite un <em>conflit de concurrence</em>.</p>\n<p>Si deux fils d’exécution Python exécutent le code du premier exemple ci-dessus, un des fils pourrait obtenir, incrémenter et enregistrer une valeur de champ après que l’autre fil l’ait obtenu de la base de données. La valeur enregistrée par le second fil d’exécution sera basé sur la valeur d’origine ; le travail du premier fil d’exécution sera tout simplement perdu.</p>\n<p>Si c’est la base de données qui est responsable de la mise à jour du champ, le processus est plus robuste : la valeur du champ sera toujours mise à jour en fonction de sa valeur en base de données au moment même de l’appel à <a class=\"reference internal\" href=\"/fr/1.11/ref/models/instances/#django.db.models.Model.save\" title=\"django.db.models.Model.save\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">save()</span></code></a> ou <code class=\"docutils literal notranslate\"><span class=\"pre\">update()</span></code>, et non pas en fonction de la valeur obtenue au moment de la création de l’instance de modèle.</p>\n</section>\n<section id=\"f-assignments-persist-after-model-save\">\n<h4>Les attributions par <code class=\"docutils literal notranslate\"><span class=\"pre\">F()</span></code> persistent après <code class=\"docutils literal notranslate\"><span class=\"pre\">Model.save()</span></code><a class=\"heading-anchor\" href=\"#f-assignments-persist-after-model-save\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Les objets <code class=\"docutils literal notranslate\"><span class=\"pre\">F()</span></code> attribués aux champs de modèles persistent après l’enregistrement de l’instance de modèle et seront appliqués pour chaque <a class=\"reference internal\" href=\"/fr/1.11/ref/models/instances/#django.db.models.Model.save\" title=\"django.db.models.Model.save\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">save()</span></code></a>. Par exemple :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">reporter</span> <span class=\"o\">=</span> <span class=\"n\">Reporters</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;Tintin&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">reporter</span><span class=\"o\">.</span><span class=\"n\">stories_filed</span> <span class=\"o\">=</span> <span class=\"n\">F</span><span class=\"p\">(</span><span class=\"s1\">&#39;stories_filed&#39;</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"mi\">1</span>\n<span class=\"n\">reporter</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">()</span>\n\n<span class=\"n\">reporter</span><span class=\"o\">.</span><span class=\"n\">name</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;Tintin Jr.&#39;</span>\n<span class=\"n\">reporter</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">()</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">stories_filed</span></code> sera mis à jour deux fois dans ce cas. SI la valeur initiale est <code class=\"docutils literal notranslate\"><span class=\"pre\">1</span></code>, la valeur finale sera <code class=\"docutils literal notranslate\"><span class=\"pre\">3</span></code>.</p>\n</section>\n<section id=\"using-f-in-filters\">\n<h4>Utilisation de <code class=\"docutils literal notranslate\"><span class=\"pre\">F()</span></code> dans les filtres<a class=\"heading-anchor\" href=\"#using-f-in-filters\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">F()</span></code> est aussi très utile dans les filtres <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code>, là où il est possible de filtrer un jeu d’objets en fonction de critères basés sur les valeurs des champs, plutôt que sur des valeurs Python.</p>\n<p>Cette utilisation est documentée dans <a class=\"reference internal\" href=\"/fr/1.11/topics/db/queries/#using-f-expressions-in-filters\"><span class=\"std std-ref\">Expressions F() dans les requêtes</span></a>.</p>\n</section>\n<section id=\"using-f-with-annotations\">\n<span id=\"id2\"></span><h4>Utilisation de <code class=\"docutils literal notranslate\"><span class=\"pre\">F()</span></code> avec les annotations<a class=\"heading-anchor\" href=\"#using-f-with-annotations\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">F()</span></code> peut être utilisée pour créer des champs dynamiques pour les modèles en combinant plusieurs champs de manière arithmétique :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">company</span> <span class=\"o\">=</span> <span class=\"n\">Company</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span>\n    <span class=\"n\">chairs_needed</span><span class=\"o\">=</span><span class=\"n\">F</span><span class=\"p\">(</span><span class=\"s1\">&#39;num_employees&#39;</span><span class=\"p\">)</span> <span class=\"o\">-</span> <span class=\"n\">F</span><span class=\"p\">(</span><span class=\"s1\">&#39;num_chairs&#39;</span><span class=\"p\">))</span>\n</code></pre></div>\n<p>Si les champs que vous combinez sont de types différents, il est nécessaire d’indiquer à Django le type de champ qui en résultera. Comme <code class=\"docutils literal notranslate\"><span class=\"pre\">F()</span></code> ne prend pas directement en charge <code class=\"docutils literal notranslate\"><span class=\"pre\">output_field</span></code>, il faut envelopper l’expression dans <a class=\"reference internal\" href=\"#django.db.models.ExpressionWrapper\" title=\"django.db.models.ExpressionWrapper\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">ExpressionWrapper</span></code></a>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">DateTimeField</span><span class=\"p\">,</span> <span class=\"n\">ExpressionWrapper</span><span class=\"p\">,</span> <span class=\"n\">F</span>\n\n<span class=\"n\">Ticket</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span>\n    <span class=\"n\">expires</span><span class=\"o\">=</span><span class=\"n\">ExpressionWrapper</span><span class=\"p\">(</span>\n        <span class=\"n\">F</span><span class=\"p\">(</span><span class=\"s1\">&#39;active_at&#39;</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"n\">F</span><span class=\"p\">(</span><span class=\"s1\">&#39;duration&#39;</span><span class=\"p\">),</span> <span class=\"n\">output_field</span><span class=\"o\">=</span><span class=\"n\">DateTimeField</span><span class=\"p\">()))</span>\n</code></pre></div>\n<p>Lorsqu’elle fait référence à des champs relationnels tels qu’une clé <code class=\"docutils literal notranslate\"><span class=\"pre\">ForeignKey</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">F()</span></code> renvoie la valeur de clé primaire plutôt qu’une instance de modèle :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"o\">&gt;&gt;</span> <span class=\"n\">car</span> <span class=\"o\">=</span> <span class=\"n\">Company</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span><span class=\"n\">built_by</span><span class=\"o\">=</span><span class=\"n\">F</span><span class=\"p\">(</span><span class=\"s1\">&#39;manufacturer&#39;</span><span class=\"p\">))[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n<span class=\"o\">&gt;&gt;</span> <span class=\"n\">car</span><span class=\"o\">.</span><span class=\"n\">manufacturer</span>\n<span class=\"o\">&lt;</span><span class=\"n\">Manufacturer</span><span class=\"p\">:</span> <span class=\"n\">Toyota</span><span class=\"o\">&gt;</span>\n<span class=\"o\">&gt;&gt;</span> <span class=\"n\">car</span><span class=\"o\">.</span><span class=\"n\">built_by</span>\n<span class=\"mi\">3</span>\n</code></pre></div>\n</section>\n</section>\n<section id=\"func-expressions\">\n<span id=\"id3\"></span><h3>Expressions <code class=\"docutils literal notranslate\"><span class=\"pre\">Func()</span></code><a class=\"heading-anchor\" href=\"#func-expressions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Les expressions <code class=\"docutils literal notranslate\"><span class=\"pre\">Func()</span></code> sont le type de base de toutes les expressions qui impliquent des fonctions de base de données telles que <code class=\"docutils literal notranslate\"><span class=\"pre\">COALESCE</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">LOWER</span></code>, ou des agrégations comme <code class=\"docutils literal notranslate\"><span class=\"pre\">SUM</span></code>. Elles peuvent être utilisées directement :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Func</span><span class=\"p\">,</span> <span class=\"n\">F</span>\n\n<span class=\"n\">queryset</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span><span class=\"n\">field_lower</span><span class=\"o\">=</span><span class=\"n\">Func</span><span class=\"p\">(</span><span class=\"n\">F</span><span class=\"p\">(</span><span class=\"s1\">&#39;field&#39;</span><span class=\"p\">),</span> <span class=\"n\">function</span><span class=\"o\">=</span><span class=\"s1\">&#39;LOWER&#39;</span><span class=\"p\">))</span>\n</code></pre></div>\n<p>ou elles peuvent être utilisées pour bâtir une bibliothèque de fonctions de base de données :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Lower</span><span class=\"p\">(</span><span class=\"n\">Func</span><span class=\"p\">):</span>\n    <span class=\"n\">function</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;LOWER&#39;</span>\n\n<span class=\"n\">queryset</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span><span class=\"n\">field_lower</span><span class=\"o\">=</span><span class=\"n\">Lower</span><span class=\"p\">(</span><span class=\"s1\">&#39;field&#39;</span><span class=\"p\">))</span>\n</code></pre></div>\n<p>Mais dans les deux cas, chaque modèle du jeu de requête résultant sera annoté avec un attribut supplémentaire <code class=\"docutils literal notranslate\"><span class=\"pre\">field_lower</span></code> dont le contenu correspondra plus ou moins au code SQL suivant :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">SELECT</span>\n    <span class=\"o\">...</span>\n    <span class=\"n\">LOWER</span><span class=\"p\">(</span><span class=\"s2\">&quot;db_table&quot;</span><span class=\"o\">.</span><span class=\"s2\">&quot;field&quot;</span><span class=\"p\">)</span> <span class=\"k\">as</span> <span class=\"s2\">&quot;field_lower&quot;</span>\n</code></pre></div>\n<p>Voir <a class=\"reference internal\" href=\"/fr/1.11/ref/models/database-functions/\"><span class=\"doc\">Fonctions de base de données</span></a> pour une liste de fonctions de base de données intégrées.</p>\n<p>L’API <code class=\"docutils literal notranslate\"><span class=\"pre\">Func</span></code> se présente comme suit :</p>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Func\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">Func</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">*</span></span><span class=\"n\"><span class=\"pre\">expressions</span></span></em>, <em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">**</span></span><span class=\"n\"><span class=\"pre\">extra</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Func\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Func.function\">\n<span class=\"sig-name descname\"><span class=\"pre\">function</span></span><a class=\"heading-anchor\" href=\"#django.db.models.Func.function\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Un attribut de classe décrivant la fonction qui sera générée. Plus précisément, <code class=\"docutils literal notranslate\"><span class=\"pre\">function</span></code> sera inséré par le substituant <code class=\"docutils literal notranslate\"><span class=\"pre\">function</span></code> à l’intérieur de <a class=\"reference internal\" href=\"#django.db.models.Func.template\" title=\"django.db.models.Func.template\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">template</span></code></a>. Sa valeur par défaut est <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code>.</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Func.template\">\n<span class=\"sig-name descname\"><span class=\"pre\">template</span></span><a class=\"heading-anchor\" href=\"#django.db.models.Func.template\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Un attribut de classe, sous forme de chaîne de format, qui décrit le code SQL généré pour cette fonction. Sa valeur par défaut est <code class=\"docutils literal notranslate\"><span class=\"pre\">'%(function)s(%(expressions)s)'</span></code>.</p>\n<p>SI vous construisez du code SQL tel que <code class=\"docutils literal notranslate\"><span class=\"pre\">strftime('%W',</span> <span class=\"pre\">'date')</span></code> et que vous avez besoin d’un caractère littéral <code class=\"docutils literal notranslate\"><span class=\"pre\">%</span></code> dans la requête, vous devez le quadrupler (<code class=\"docutils literal notranslate\"><span class=\"pre\">%%%%</span></code>) dans l’attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">template</span></code> car la chaîne est interpolée deux fois : une fois pendant l’interpolation du gabarit dans <code class=\"docutils literal notranslate\"><span class=\"pre\">as_sql()</span></code>, et une autre fois dans l’interpolation SQL avec les paramètres de requête dans le curseur de base de données.</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Func.arg_joiner\">\n<span class=\"sig-name descname\"><span class=\"pre\">arg_joiner</span></span><a class=\"heading-anchor\" href=\"#django.db.models.Func.arg_joiner\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Un attribut de classe qui précise la séquence de caractères utilisée pour joindre les éléments de la liste d”<code class=\"docutils literal notranslate\"><span class=\"pre\">expressions</span></code>. Sa valeur par défaut est <code class=\"docutils literal notranslate\"><span class=\"pre\">',</span> <span class=\"pre\">'</span></code>.</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Func.arity\">\n<span class=\"sig-name descname\"><span class=\"pre\">arity</span></span><a class=\"heading-anchor\" href=\"#django.db.models.Func.arity\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><aside class=\"version-note version-added\" data-version=\"1.10\">\n<p class=\"version-note-title\">New in Django 1.10</p></aside>\n<p>Un attribut de classe qui indique le nombre de paramètres acceptés par la fonction. Si cet attribut est défini et que la fonction est appelée avec un nombre d’expressions différent, une exception <code class=\"docutils literal notranslate\"><span class=\"pre\">TypeError</span></code> sera générée. La valeur par défaut est <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code>.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Func.as_sql\">\n<span class=\"sig-name descname\"><span class=\"pre\">as_sql</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">compiler</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">connection</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">function</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">template</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">arg_joiner</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">**</span></span><span class=\"n\"><span class=\"pre\">extra_context</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Func.as_sql\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Produit le code SQL pour la fonction de base de données.</p>\n<p>Les méthodes <code class=\"docutils literal notranslate\"><span class=\"pre\">as_vendor()</span></code> devraient utiliser les paramètres <code class=\"docutils literal notranslate\"><span class=\"pre\">function</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">template</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">arg_joiner</span></code> et tout autre paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">**extra_context</span></code> pour adapter le code SQL en cas de besoin. Par exemple :</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"default\"><figcaption class=\"code-block-caption\"><code>django/db/models/functions.py</code></figcaption><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"django/db/models/functions.py\"><code><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">ConcatPair</span><span class=\"p\">(</span><span class=\"n\">Func</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n    <span class=\"n\">function</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;CONCAT&#39;</span>\n    <span class=\"o\">...</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">as_mysql</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">compiler</span><span class=\"p\">,</span> <span class=\"n\">connection</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"nb\">super</span><span class=\"p\">(</span><span class=\"n\">ConcatPair</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">as_sql</span><span class=\"p\">(</span>\n            <span class=\"n\">compiler</span><span class=\"p\">,</span> <span class=\"n\">connection</span><span class=\"p\">,</span>\n            <span class=\"n\">function</span><span class=\"o\">=</span><span class=\"s1\">&#39;CONCAT_WS&#39;</span><span class=\"p\">,</span>\n            <span class=\"n\">template</span><span class=\"o\">=</span><span class=\"s2\">&quot;</span><span class=\"si\">%(function)s</span><span class=\"s2\">(&#39;&#39;, </span><span class=\"si\">%(expressions)s</span><span class=\"s2\">)&quot;</span><span class=\"p\">,</span>\n        <span class=\"p\">)</span>\n</code></pre></figure>\n<aside class=\"version-note version-changed\" data-version=\"1.10\">\n<p class=\"version-note-title\">Changed in Django 1.10</p><p>La prise en charge des paramètres <code class=\"docutils literal notranslate\"><span class=\"pre\">arg_joiner</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">**extra_context</span></code> a été ajoutée.</p>\n</aside>\n</dd></dl>\n\n</dd></dl>\n\n<p>Le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">*expressions</span></code> est une liste d’expressions positionnelles auxquelles la fonction s’applique. Les expressions sont converties en chaînes, jointes par <code class=\"docutils literal notranslate\"><span class=\"pre\">arg_joiner</span></code>, puis insérées dans <code class=\"docutils literal notranslate\"><span class=\"pre\">template</span></code> par le substituant <code class=\"docutils literal notranslate\"><span class=\"pre\">expressions</span></code>.</p>\n<p>Les paramètres positionnels peuvent être des expressions ou des valeurs Python. Les chaînes sont censées être des références de colonnes et seront enveloppées dans des expressions <code class=\"docutils literal notranslate\"><span class=\"pre\">F()</span></code> alors que les autres valeurs sont enveloppées dans des expressions <code class=\"docutils literal notranslate\"><span class=\"pre\">Value()</span></code>.</p>\n<p>Les paramètres nommés <code class=\"docutils literal notranslate\"><span class=\"pre\">**extra</span></code> sont des paires <code class=\"docutils literal notranslate\"><span class=\"pre\">clé=valeur</span></code> qui peuvent être insérées dans l’attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">template</span></code>. Les mots-clés <code class=\"docutils literal notranslate\"><span class=\"pre\">function</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">template</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">arg_joiner</span></code> peuvent être utilisés pour remplacer les attributs de même nom sans avoir besoin de définir une classe spécifique. <code class=\"docutils literal notranslate\"><span class=\"pre\">output_field</span></code> peut être utilisé pour définir le type de la valeur renvoyée.</p>\n</section>\n<section id=\"aggregate-expressions\">\n<h3>Expressions <code class=\"docutils literal notranslate\"><span class=\"pre\">Aggregate()</span></code><a class=\"heading-anchor\" href=\"#aggregate-expressions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Une expression d’agrégation est un cas particulier d’une <a class=\"reference internal\" href=\"#func-expressions\"><span class=\"std std-ref\">expression Func()</span></a> qui informe la requête qu’une clause <code class=\"docutils literal notranslate\"><span class=\"pre\">GROUP</span> <span class=\"pre\">BY</span></code> est nécessaire. Toutes les <a class=\"reference internal\" href=\"/fr/1.11/ref/models/querysets/#aggregation-functions\"><span class=\"std std-ref\">fonctions d’agrégation</span></a> comme <code class=\"docutils literal notranslate\"><span class=\"pre\">Sum()</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">Count()</span></code> héritent de <code class=\"docutils literal notranslate\"><span class=\"pre\">Aggregate()</span></code>.</p>\n<p>Comme les <code class=\"docutils literal notranslate\"><span class=\"pre\">Aggregate</span></code> sont des des expressions et enveloppent des expressions, il est possible de représenter des calculs complexes :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Count</span>\n\n<span class=\"n\">Company</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span>\n    <span class=\"n\">managers_required</span><span class=\"o\">=</span><span class=\"p\">(</span><span class=\"n\">Count</span><span class=\"p\">(</span><span class=\"s1\">&#39;num_employees&#39;</span><span class=\"p\">)</span> <span class=\"o\">/</span> <span class=\"mi\">4</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"n\">Count</span><span class=\"p\">(</span><span class=\"s1\">&#39;num_managers&#39;</span><span class=\"p\">))</span>\n</code></pre></div>\n<p>L’API <code class=\"docutils literal notranslate\"><span class=\"pre\">Aggregate</span></code> se présente comme suit :</p>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Aggregate\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">Aggregate</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">expression</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">output_field</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">**</span></span><span class=\"n\"><span class=\"pre\">extra</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Aggregate\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Aggregate.template\">\n<span class=\"sig-name descname\"><span class=\"pre\">template</span></span><a class=\"heading-anchor\" href=\"#django.db.models.Aggregate.template\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Un attribut de classe, sous forme de chaîne de format, qui décrit le code SQL généré pour cette agrégation. Sa valeur par défaut est <code class=\"docutils literal notranslate\"><span class=\"pre\">'%(function)s(%(expressions)s)'</span></code>.</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Aggregate.function\">\n<span class=\"sig-name descname\"><span class=\"pre\">function</span></span><a class=\"heading-anchor\" href=\"#django.db.models.Aggregate.function\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Un attribut de classe décrivant la fonction d’agrégation qui sera générée. Plus précisément, <code class=\"docutils literal notranslate\"><span class=\"pre\">function</span></code> sera inséré par le substituant <code class=\"docutils literal notranslate\"><span class=\"pre\">function</span></code> à l’intérieur de <a class=\"reference internal\" href=\"#django.db.models.Aggregate.template\" title=\"django.db.models.Aggregate.template\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">template</span></code></a>. Sa valeur par défaut est <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code>.</p>\n</dd></dl>\n\n</dd></dl>\n\n<p>Le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">expression</span></code> peut être le nom d’un champ de modèle ou une autre expression. Il sera converti en texte et utilisé comme substituant <code class=\"docutils literal notranslate\"><span class=\"pre\">expressions</span></code> à l’intérieur de <code class=\"docutils literal notranslate\"><span class=\"pre\">template</span></code>.</p>\n<p>Le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">output_field</span></code> doit être une instance de champ de modèle, comme <code class=\"docutils literal notranslate\"><span class=\"pre\">IntegerField()</span></code> ou <code class=\"docutils literal notranslate\"><span class=\"pre\">BooleanField()</span></code>, dans laquelle Django chargera la valeur après qu’elle aura été reçue de la base de données. Aucun paramètre n’est habituellement nécessaire lors de la création de l’instance du champ de modèle car aucun paramètre lié à la validation de données (<code class=\"docutils literal notranslate\"><span class=\"pre\">max_length</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">max_digits</span></code>, etc.) ne sera appliqué à la valeur résultante de l’expression.</p>\n<p>Notez que <code class=\"docutils literal notranslate\"><span class=\"pre\">output_field</span></code> n’est obligatoire que lorsque Django est incapable de déterminer le type de champ du résultat. Les expressions complexes qui mélangent des types de champs doivent définir avec <code class=\"docutils literal notranslate\"><span class=\"pre\">output_field</span></code> le type de résultat attendu. Par exemple, l’addition d’un <code class=\"docutils literal notranslate\"><span class=\"pre\">IntegerField()</span></code> et d’un <code class=\"docutils literal notranslate\"><span class=\"pre\">FloatField()</span></code> va probablement demander la définition de <code class=\"docutils literal notranslate\"><span class=\"pre\">output_field=FloatField()</span></code>.</p>\n<p>Les paramètres nommés <code class=\"docutils literal notranslate\"><span class=\"pre\">**extra</span></code> sont des paires <code class=\"docutils literal notranslate\"><span class=\"pre\">clé=valeur</span></code> qui peuvent être insérées par interpolation dans l’attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">template</span></code>.</p>\n</section>\n<section id=\"creating-your-own-aggregate-functions\">\n<h3>Création de ses propres fonctions d’agrégation<a class=\"heading-anchor\" href=\"#creating-your-own-aggregate-functions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>La création de ses propres agrégations est très facile. Il faut définir au minimum <code class=\"docutils literal notranslate\"><span class=\"pre\">function</span></code>, mais vous pouvez aussi personnaliser complètement le code SQL produit. Voici un court exemple :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Aggregate</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Count</span><span class=\"p\">(</span><span class=\"n\">Aggregate</span><span class=\"p\">):</span>\n    <span class=\"c1\"># supports COUNT(distinct field)</span>\n    <span class=\"n\">function</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;COUNT&#39;</span>\n    <span class=\"n\">template</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;</span><span class=\"si\">%(function)s</span><span class=\"s1\">(</span><span class=\"si\">%(distinct)s%(expressions)s</span><span class=\"s1\">)&#39;</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">expression</span><span class=\"p\">,</span> <span class=\"n\">distinct</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">extra</span><span class=\"p\">):</span>\n        <span class=\"nb\">super</span><span class=\"p\">(</span><span class=\"n\">Count</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">(</span>\n            <span class=\"n\">expression</span><span class=\"p\">,</span>\n            <span class=\"n\">distinct</span><span class=\"o\">=</span><span class=\"s1\">&#39;DISTINCT &#39;</span> <span class=\"k\">if</span> <span class=\"n\">distinct</span> <span class=\"k\">else</span> <span class=\"s1\">&#39;&#39;</span><span class=\"p\">,</span>\n            <span class=\"n\">output_field</span><span class=\"o\">=</span><span class=\"n\">IntegerField</span><span class=\"p\">(),</span>\n            <span class=\"o\">**</span><span class=\"n\">extra</span>\n        <span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"value-expressions\">\n<h3>Expressions <code class=\"docutils literal notranslate\"><span class=\"pre\">Value()</span></code><a class=\"heading-anchor\" href=\"#value-expressions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Value\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">Value</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">value</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">output_field</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Value\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Un objet <code class=\"docutils literal notranslate\"><span class=\"pre\">Value()</span></code> représente le composant le plus petit possible d’une expression : une simple valeur. Lorsque vous avez besoin de représenter la valeur d’un nombre entier, d’un booléen ou d’une chaîne à l’intérieur d’une expression, vous pouvez insérer cette valeur dans un objet <code class=\"docutils literal notranslate\"><span class=\"pre\">Value()</span></code>.</p>\n<p>Il est rarement nécessaire de faire appel directement à <code class=\"docutils literal notranslate\"><span class=\"pre\">Value()</span></code>. Lorsque vous écrivez l’expression <code class=\"docutils literal notranslate\"><span class=\"pre\">F('champ')</span> <span class=\"pre\">+</span> <span class=\"pre\">1</span></code>, Django insère implicitement le <code class=\"docutils literal notranslate\"><span class=\"pre\">1</span></code> dans un objet <code class=\"docutils literal notranslate\"><span class=\"pre\">Value()</span></code>, ce qui permet d’utiliser des valeurs simples dans des expressions plus complexes. <code class=\"docutils literal notranslate\"><span class=\"pre\">Value()</span></code> devra être utilisé lors du passage d’une chaîne à une expression. La plupart des expressions interprètent un paramètre textuel comme le nom d’un champ, comme par exemple <code class=\"docutils literal notranslate\"><span class=\"pre\">Lower('name')</span></code>.</p>\n<p>Le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">value</span></code> décrit la valeur à inclure dans l’expression, comme <code class=\"docutils literal notranslate\"><span class=\"pre\">1</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> ou <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code>. Django sait comment convertir ces valeurs Python dans le bon type de la base de données correspondante.</p>\n<p>Le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">output_field</span></code> doit être une instance de champ de modèle, comme <code class=\"docutils literal notranslate\"><span class=\"pre\">IntegerField()</span></code> ou <code class=\"docutils literal notranslate\"><span class=\"pre\">BooleanField()</span></code>, dans laquelle Django chargera la valeur après qu’elle aura été reçue de la base de données. Aucun paramètre n’est habituellement nécessaire lors de la création de l’instance du champ de modèle car aucun paramètre lié à la validation de données (<code class=\"docutils literal notranslate\"><span class=\"pre\">max_length</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">max_digits</span></code>, etc.) ne sera appliqué à la valeur résultante de l’expression.</p>\n</section>\n<section id=\"expressionwrapper-expressions\">\n<h3>Expressions <code class=\"docutils literal notranslate\"><span class=\"pre\">ExpressionWrapper()</span></code><a class=\"heading-anchor\" href=\"#expressionwrapper-expressions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.ExpressionWrapper\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">ExpressionWrapper</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">expression</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">output_field</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.ExpressionWrapper\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">ExpressionWrapper</span></code> ne fait qu’entourer une autre expression et permet d’accéder aux propriétés, telles que <code class=\"docutils literal notranslate\"><span class=\"pre\">output_field</span></code>, qui pourraient ne pas être disponibles dans d’autres expressions. <code class=\"docutils literal notranslate\"><span class=\"pre\">ExpressionWrapper</span></code> est nécessaire lorsqu’on utilise de l’arithmétique avec les expressions <code class=\"docutils literal notranslate\"><span class=\"pre\">F()</span></code> avec différents types, comme décrit dans <a class=\"reference internal\" href=\"#using-f-with-annotations\"><span class=\"std std-ref\">Utilisation de F() avec les annotations</span></a>.</p>\n</section>\n<section id=\"conditional-expressions\">\n<h3>Expressions conditionnelles<a class=\"heading-anchor\" href=\"#conditional-expressions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Les expressions conditionnelles permettent d’utiliser de la logique <a class=\"reference external\" href=\"https://docs.python.org/3/reference/compound_stmts.html#if\" title=\"(disponible dans Python v3.14)\"><code class=\"xref std std-keyword docutils literal notranslate\"><span class=\"pre\">if</span></code></a> … <a class=\"reference external\" href=\"https://docs.python.org/3/reference/compound_stmts.html#elif\" title=\"(disponible dans Python v3.14)\"><code class=\"xref std std-keyword docutils literal notranslate\"><span class=\"pre\">elif</span></code></a> … <a class=\"reference external\" href=\"https://docs.python.org/3/reference/compound_stmts.html#else\" title=\"(disponible dans Python v3.14)\"><code class=\"xref std std-keyword docutils literal notranslate\"><span class=\"pre\">else</span></code></a> dans les requêtes. Django prend nativement en charge les expressions SQL <code class=\"docutils literal notranslate\"><span class=\"pre\">CASE</span></code>. Pour plus de détails, consultez <a class=\"reference internal\" href=\"/fr/1.11/ref/models/conditional-expressions/\"><span class=\"doc\">Expressions conditionnelles</span></a>.</p>\n</section>\n<section id=\"subquery-expressions\">\n<h3>Expressions <code class=\"docutils literal notranslate\"><span class=\"pre\">Subquery()</span></code><a class=\"heading-anchor\" href=\"#subquery-expressions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Subquery\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">Subquery</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">queryset</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">output_field</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Subquery\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<aside class=\"version-note version-added\" data-version=\"1.11\">\n<p class=\"version-note-title\">New in Django 1.11</p></aside>\n<p>Il est possible d’ajouter des sous-requêtes explicites à un objet <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> en utilisant l’expression <code class=\"docutils literal notranslate\"><span class=\"pre\">Subquery</span></code>.</p>\n<p>Par exemple, pour annoter chaque <code class=\"docutils literal notranslate\"><span class=\"pre\">post</span></code> avec l’adresse de courriel de l’auteur du commentaire le plus récent de ce <code class=\"docutils literal notranslate\"><span class=\"pre\">post</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">OuterRef</span><span class=\"p\">,</span> <span class=\"n\">Subquery</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">newest</span> <span class=\"o\">=</span> <span class=\"n\">Comment</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">post</span><span class=\"o\">=</span><span class=\"n\">OuterRef</span><span class=\"p\">(</span><span class=\"s1\">&#39;pk&#39;</span><span class=\"p\">))</span><span class=\"o\">.</span><span class=\"n\">order_by</span><span class=\"p\">(</span><span class=\"s1\">&#39;-created_at&#39;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Post</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span><span class=\"n\">newest_commenter_email</span><span class=\"o\">=</span><span class=\"n\">Subquery</span><span class=\"p\">(</span><span class=\"n\">newest</span><span class=\"o\">.</span><span class=\"n\">values</span><span class=\"p\">(</span><span class=\"s1\">&#39;email&#39;</span><span class=\"p\">)[:</span><span class=\"mi\">1</span><span class=\"p\">]))</span>\n</code></pre></div>\n<p>Avec PostgreSQL, le code SQL ressemble à ceci :</p>\n<div class=\"code-block\" data-language=\"sql\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">SQL</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"SQL code\"><code><span class=\"k\">SELECT</span><span class=\"w\"> </span><span class=\"ss\">&quot;post&quot;</span><span class=\"p\">.</span><span class=\"ss\">&quot;id&quot;</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"p\">(</span>\n<span class=\"w\">    </span><span class=\"k\">SELECT</span><span class=\"w\"> </span><span class=\"n\">U0</span><span class=\"p\">.</span><span class=\"ss\">&quot;email&quot;</span>\n<span class=\"w\">    </span><span class=\"k\">FROM</span><span class=\"w\"> </span><span class=\"ss\">&quot;comment&quot;</span><span class=\"w\"> </span><span class=\"n\">U0</span>\n<span class=\"w\">    </span><span class=\"k\">WHERE</span><span class=\"w\"> </span><span class=\"n\">U0</span><span class=\"p\">.</span><span class=\"ss\">&quot;post_id&quot;</span><span class=\"w\"> </span><span class=\"o\">=</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"ss\">&quot;post&quot;</span><span class=\"p\">.</span><span class=\"ss\">&quot;id&quot;</span><span class=\"p\">)</span>\n<span class=\"w\">    </span><span class=\"k\">ORDER</span><span class=\"w\"> </span><span class=\"k\">BY</span><span class=\"w\"> </span><span class=\"n\">U0</span><span class=\"p\">.</span><span class=\"ss\">&quot;created_at&quot;</span><span class=\"w\"> </span><span class=\"k\">DESC</span><span class=\"w\"> </span><span class=\"k\">LIMIT</span><span class=\"w\"> </span><span class=\"mi\">1</span>\n<span class=\"p\">)</span><span class=\"w\"> </span><span class=\"k\">AS</span><span class=\"w\"> </span><span class=\"ss\">&quot;newest_commenter_email&quot;</span><span class=\"w\"> </span><span class=\"k\">FROM</span><span class=\"w\"> </span><span class=\"ss\">&quot;post&quot;</span>\n</code></pre></div>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>Les exemples de cette section sont conçus pour montrer comment forcer Django à exécuter une sous-requête. Dans certains cas, il serait possible d’écrire une requête équivalente qui effectue la même tâche plus clairement ou plus efficacement.</p>\n</aside>\n<section id=\"referencing-columns-from-the-outer-queryset\">\n<h4>Référencement des colonnes de la requête parente<a class=\"heading-anchor\" href=\"#referencing-columns-from-the-outer-queryset\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.OuterRef\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">OuterRef</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">field</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.OuterRef\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<aside class=\"version-note version-added\" data-version=\"1.11\">\n<p class=\"version-note-title\">New in Django 1.11</p></aside>\n<p>Utilisez <code class=\"docutils literal notranslate\"><span class=\"pre\">OuterRef</span></code> lorsqu’un jeu de requête dans une <code class=\"docutils literal notranslate\"><span class=\"pre\">Subquery</span></code> a besoin de se référer à un champ de la requête parente. Il se comporte comme une expression <a class=\"reference internal\" href=\"#django.db.models.F\" title=\"django.db.models.F\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">F</span></code></a> sauf que le contrôle vérifiant s’il se réfère à un champ valable n’est pas effectué avant que la requête parente ne soit résolue.</p>\n<p>Des instances de <code class=\"docutils literal notranslate\"><span class=\"pre\">OuterRef</span></code> peuvent être utilisées en lien avec des instances imbriquées de <code class=\"docutils literal notranslate\"><span class=\"pre\">Subquery</span></code> pour se référer à un jeu de requête supérieur qui n’est pas le parent immédiat. Par exemple, ce jeu de requête devrait se trouver dans une paire imbriquée d’instances <code class=\"docutils literal notranslate\"><span class=\"pre\">Subquery</span></code> pour être résolu correctement :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">author</span><span class=\"o\">=</span><span class=\"n\">OuterRef</span><span class=\"p\">(</span><span class=\"n\">OuterRef</span><span class=\"p\">(</span><span class=\"s1\">&#39;pk&#39;</span><span class=\"p\">)))</span>\n</code></pre></div>\n</section>\n<section id=\"limiting-a-subquery-to-a-single-column\">\n<h4>Limite d’une sous-requête à une seule colonne<a class=\"heading-anchor\" href=\"#limiting-a-subquery-to-a-single-column\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Dans certaines circonstances, une seule colonne doit être renvoyée d’une sous-requête <code class=\"docutils literal notranslate\"><span class=\"pre\">Subquery</span></code>, par exemple quand on veut utiliser la sous-requête comme cible d’une recherche <code class=\"docutils literal notranslate\"><span class=\"pre\">__in</span></code>. Pour renvoyer tous les commentaires de <code class=\"docutils literal notranslate\"><span class=\"pre\">posts</span></code> publiés durant les dernières 24 heures :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">datetime</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">timedelta</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.utils</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">timezone</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">one_day_ago</span> <span class=\"o\">=</span> <span class=\"n\">timezone</span><span class=\"o\">.</span><span class=\"n\">now</span><span class=\"p\">()</span> <span class=\"o\">-</span> <span class=\"n\">timedelta</span><span class=\"p\">(</span><span class=\"n\">days</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">posts</span> <span class=\"o\">=</span> <span class=\"n\">Post</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">published_at__gte</span><span class=\"o\">=</span><span class=\"n\">one_day_ago</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Comment</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">post__in</span><span class=\"o\">=</span><span class=\"n\">Subquery</span><span class=\"p\">(</span><span class=\"n\">posts</span><span class=\"o\">.</span><span class=\"n\">values</span><span class=\"p\">(</span><span class=\"s1\">&#39;pk&#39;</span><span class=\"p\">)))</span>\n</code></pre></div>\n<p>Dans ce cas, la sous-requête doit utiliser <a class=\"reference internal\" href=\"/fr/1.11/ref/models/querysets/#django.db.models.query.QuerySet.values\" title=\"django.db.models.query.QuerySet.values\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">values()</span></code></a> pour ne renvoyer qu’une seule colonne : la clé primaire du <code class=\"docutils literal notranslate\"><span class=\"pre\">post</span></code>.</p>\n</section>\n<section id=\"limiting-the-subquery-to-a-single-row\">\n<h4>Limite de la sous-requête à une seule ligne<a class=\"heading-anchor\" href=\"#limiting-the-subquery-to-a-single-row\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Pour empêcher une sous-requête de renvoyer plusieurs lignes, une segmentation (<code class=\"docutils literal notranslate\"><span class=\"pre\">[:1]</span></code>) du résultat de requête est appliquée :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">subquery</span> <span class=\"o\">=</span> <span class=\"n\">Subquery</span><span class=\"p\">(</span><span class=\"n\">newest</span><span class=\"o\">.</span><span class=\"n\">values</span><span class=\"p\">(</span><span class=\"s1\">&#39;email&#39;</span><span class=\"p\">)[:</span><span class=\"mi\">1</span><span class=\"p\">])</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Post</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span><span class=\"n\">newest_commenter_email</span><span class=\"o\">=</span><span class=\"n\">subquery</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Dans ce cas, la sous-requête ne doit renvoyer qu’une seule colonne <em>et</em> une seule ligne : l’adresse électronique du commentaire créé le plus récent.</p>\n<p>(L’utilisation de <a class=\"reference internal\" href=\"/fr/1.11/ref/models/querysets/#django.db.models.query.QuerySet.get\" title=\"django.db.models.query.QuerySet.get\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get()</span></code></a> à la place d’une segmentation ne fonctionnerait pas car <code class=\"docutils literal notranslate\"><span class=\"pre\">OuterRef</span></code> ne peut pas être résolu tant que le résultat de requête n’est pas utilisé dans une sous-requête <code class=\"docutils literal notranslate\"><span class=\"pre\">Subquery</span></code>.)</p>\n</section>\n<section id=\"exists-subqueries\">\n<h4>Sous-requêtes <code class=\"docutils literal notranslate\"><span class=\"pre\">Exists()</span></code><a class=\"heading-anchor\" href=\"#exists-subqueries\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Exists\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">Exists</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">queryset</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Exists\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<aside class=\"version-note version-added\" data-version=\"1.11\">\n<p class=\"version-note-title\">New in Django 1.11</p></aside>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">Exists</span></code> est une sous-classe de <code class=\"docutils literal notranslate\"><span class=\"pre\">Subquery</span></code> utilisant une instruction SQL <code class=\"docutils literal notranslate\"><span class=\"pre\">EXISTS</span></code>. Dans bien des cas, la performance sera meilleure qu’une sous-requête car la base de données est capable de stopper l’évaluation de la sous-requête dès qu’une première ligne correspondante est trouvée.</p>\n<p>Par exemple, pour annoter chaque <code class=\"docutils literal notranslate\"><span class=\"pre\">post</span></code> avec une indication de la présence ou non d’un commentaire durant la journée écoulée :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Exists</span><span class=\"p\">,</span> <span class=\"n\">OuterRef</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">datetime</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">timedelta</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.utils</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">timezone</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">one_day_ago</span> <span class=\"o\">=</span> <span class=\"n\">timezone</span><span class=\"o\">.</span><span class=\"n\">now</span><span class=\"p\">()</span> <span class=\"o\">-</span> <span class=\"n\">timedelta</span><span class=\"p\">(</span><span class=\"n\">days</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">recent_comments</span> <span class=\"o\">=</span> <span class=\"n\">Comment</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"n\">post</span><span class=\"o\">=</span><span class=\"n\">OuterRef</span><span class=\"p\">(</span><span class=\"s1\">&#39;pk&#39;</span><span class=\"p\">),</span>\n<span class=\"gp\">... </span>    <span class=\"n\">created_at__gte</span><span class=\"o\">=</span><span class=\"n\">one_day_ago</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Post</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span><span class=\"n\">recent_comment</span><span class=\"o\">=</span><span class=\"n\">Exists</span><span class=\"p\">(</span><span class=\"n\">recent_comments</span><span class=\"p\">))</span>\n</code></pre></div>\n<p>Avec PostgreSQL, le code SQL ressemble à ceci :</p>\n<div class=\"code-block\" data-language=\"sql\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">SQL</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"SQL code\"><code><span class=\"k\">SELECT</span><span class=\"w\"> </span><span class=\"ss\">&quot;post&quot;</span><span class=\"p\">.</span><span class=\"ss\">&quot;id&quot;</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"ss\">&quot;post&quot;</span><span class=\"p\">.</span><span class=\"ss\">&quot;published_at&quot;</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"k\">EXISTS</span><span class=\"p\">(</span>\n<span class=\"w\">    </span><span class=\"k\">SELECT</span><span class=\"w\"> </span><span class=\"n\">U0</span><span class=\"p\">.</span><span class=\"ss\">&quot;id&quot;</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"n\">U0</span><span class=\"p\">.</span><span class=\"ss\">&quot;post_id&quot;</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"n\">U0</span><span class=\"p\">.</span><span class=\"ss\">&quot;email&quot;</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"n\">U0</span><span class=\"p\">.</span><span class=\"ss\">&quot;created_at&quot;</span>\n<span class=\"w\">    </span><span class=\"k\">FROM</span><span class=\"w\"> </span><span class=\"ss\">&quot;comment&quot;</span><span class=\"w\"> </span><span class=\"n\">U0</span>\n<span class=\"w\">    </span><span class=\"k\">WHERE</span><span class=\"w\"> </span><span class=\"p\">(</span>\n<span class=\"w\">        </span><span class=\"n\">U0</span><span class=\"p\">.</span><span class=\"ss\">&quot;created_at&quot;</span><span class=\"w\"> </span><span class=\"o\">&gt;=</span><span class=\"w\"> </span><span class=\"n\">YYYY</span><span class=\"o\">-</span><span class=\"n\">MM</span><span class=\"o\">-</span><span class=\"n\">DD</span><span class=\"w\"> </span><span class=\"n\">HH</span><span class=\"p\">:</span><span class=\"n\">MM</span><span class=\"p\">:</span><span class=\"n\">SS</span><span class=\"w\"> </span><span class=\"k\">AND</span>\n<span class=\"w\">        </span><span class=\"n\">U0</span><span class=\"p\">.</span><span class=\"ss\">&quot;post_id&quot;</span><span class=\"w\"> </span><span class=\"o\">=</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"ss\">&quot;post&quot;</span><span class=\"p\">.</span><span class=\"ss\">&quot;id&quot;</span><span class=\"p\">)</span>\n<span class=\"w\">    </span><span class=\"p\">)</span>\n<span class=\"p\">)</span><span class=\"w\"> </span><span class=\"k\">AS</span><span class=\"w\"> </span><span class=\"ss\">&quot;recent_comment&quot;</span><span class=\"w\"> </span><span class=\"k\">FROM</span><span class=\"w\"> </span><span class=\"ss\">&quot;post&quot;</span>\n</code></pre></div>\n<p>Il n’est pas nécessaire de forcer <code class=\"docutils literal notranslate\"><span class=\"pre\">Exists</span></code> à se référer à une seule colonne, car les colonnes sont ignorées et un résultat booléen est renvoyé. De même, comme le tri ne joue pas de rôle dans une sous-requête SQL <code class=\"docutils literal notranslate\"><span class=\"pre\">EXISTS</span></code> et ne ferait que baisser la performance, il est automatiquement enlevé.</p>\n<p>Il est possible d’effectuer un <code class=\"docutils literal notranslate\"><span class=\"pre\">NOT</span> <span class=\"pre\">EXISTS</span></code> avec <code class=\"docutils literal notranslate\"><span class=\"pre\">~Exists()</span></code>.</p>\n</section>\n<section id=\"filtering-on-a-subquery-expression\">\n<h4>Filtrage sur une expression <code class=\"docutils literal notranslate\"><span class=\"pre\">Subquery</span></code><a class=\"heading-anchor\" href=\"#filtering-on-a-subquery-expression\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Il n’est pas possible de filtrer directement en utilisant <code class=\"docutils literal notranslate\"><span class=\"pre\">Subquery</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">Exists</span></code>, par ex. :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Post</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">Exists</span><span class=\"p\">(</span><span class=\"n\">recent_comments</span><span class=\"p\">))</span>\n<span class=\"gp\">...</span>\n<span class=\"go\">TypeError: &#39;Exists&#39; object is not iterable</span>\n</code></pre></div>\n<p>Pour filtrer une expression de sous-requête, vous devez commencer par annoter le jeu de requête, puis filtrer sur la base de cette annotation :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Post</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"n\">recent_comment</span><span class=\"o\">=</span><span class=\"n\">Exists</span><span class=\"p\">(</span><span class=\"n\">recent_comments</span><span class=\"p\">),</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">recent_comment</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"using-aggregates-within-a-subquery-expression\">\n<h4>Utilisation d’agrégation dans une expression <code class=\"docutils literal notranslate\"><span class=\"pre\">Subquery</span></code><a class=\"heading-anchor\" href=\"#using-aggregates-within-a-subquery-expression\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Il est possible d’utiliser des agrégats dans une sous-requête, mais cela nécessite une combinaison spécifique de <a class=\"reference internal\" href=\"/fr/1.11/ref/models/querysets/#django.db.models.query.QuerySet.filter\" title=\"django.db.models.query.QuerySet.filter\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">filter()</span></code></a>, <a class=\"reference internal\" href=\"/fr/1.11/ref/models/querysets/#django.db.models.query.QuerySet.values\" title=\"django.db.models.query.QuerySet.values\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">values()</span></code></a> et <a class=\"reference internal\" href=\"/fr/1.11/ref/models/querysets/#django.db.models.query.QuerySet.annotate\" title=\"django.db.models.query.QuerySet.annotate\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">annotate()</span></code></a> afin d’obtenir un groupement correct dans la sous-requête.</p>\n<p>En supposant que les deux modèles ont un champ <code class=\"docutils literal notranslate\"><span class=\"pre\">length</span></code>, voici comment trouver les <code class=\"docutils literal notranslate\"><span class=\"pre\">posts</span></code> dont la longueur est plus grande que la longueur totale de tous les commentaires ensemble :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">OuterRef</span><span class=\"p\">,</span> <span class=\"n\">Subquery</span><span class=\"p\">,</span> <span class=\"n\">Sum</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">comments</span> <span class=\"o\">=</span> <span class=\"n\">Comment</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">post</span><span class=\"o\">=</span><span class=\"n\">OuterRef</span><span class=\"p\">(</span><span class=\"s1\">&#39;pk&#39;</span><span class=\"p\">))</span><span class=\"o\">.</span><span class=\"n\">order_by</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">values</span><span class=\"p\">(</span><span class=\"s1\">&#39;post&#39;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">total_comments</span> <span class=\"o\">=</span> <span class=\"n\">comments</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span><span class=\"n\">total</span><span class=\"o\">=</span><span class=\"n\">Sum</span><span class=\"p\">(</span><span class=\"s1\">&#39;length&#39;</span><span class=\"p\">))</span><span class=\"o\">.</span><span class=\"n\">values</span><span class=\"p\">(</span><span class=\"s1\">&#39;total&#39;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Post</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">length__gt</span><span class=\"o\">=</span><span class=\"n\">Subquery</span><span class=\"p\">(</span><span class=\"n\">total_comments</span><span class=\"p\">))</span>\n</code></pre></div>\n<p>Le premier <code class=\"docutils literal notranslate\"><span class=\"pre\">filter(...)</span></code> limite la sous-requête aux paramètres qui nous intéressent. <code class=\"docutils literal notranslate\"><span class=\"pre\">order_by()</span></code> enlève le tri par défaut (le cas échéant) du modèle <code class=\"docutils literal notranslate\"><span class=\"pre\">Comment</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">values('post')</span></code> agrège les commentaires par <code class=\"docutils literal notranslate\"><span class=\"pre\">Post</span></code>. Pour terminer, <code class=\"docutils literal notranslate\"><span class=\"pre\">annotate(...)</span></code> effectue l’agrégation. L’ordre dans lequel sont appliqués ces méthodes de requête est important. Dans ce cas, comme la sous-requête doit être limitée à une seule colonne, <code class=\"docutils literal notranslate\"><span class=\"pre\">values('total')</span></code> est obligatoire.</p>\n<p>Il s’agit de la seule manière d’effectuer une agrégation à l’intérieur d’une sous-requête, car <a class=\"reference internal\" href=\"/fr/1.11/ref/models/querysets/#django.db.models.query.QuerySet.aggregate\" title=\"django.db.models.query.QuerySet.aggregate\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">aggregate()</span></code></a> procède à l’évaluation du jeu de requête (et lorsqu’il existe une <code class=\"docutils literal notranslate\"><span class=\"pre\">OuterRef</span></code>, celle-ci ne pourrait pas être résolue).</p>\n</section>\n</section>\n<section id=\"raw-sql-expressions\">\n<h3>Expressions SQL brutes<a class=\"heading-anchor\" href=\"#raw-sql-expressions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.expressions.RawSQL\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">RawSQL</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">sql</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">params</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">output_field</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.expressions.RawSQL\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Parfois, les expressions de base de données ne peuvent pas facilement exprimer une clause <code class=\"docutils literal notranslate\"><span class=\"pre\">WHERE</span></code> complexe. Dans ces cas limites, utilisez l’expression <code class=\"docutils literal notranslate\"><span class=\"pre\">RawSQL</span></code>. Par exemple :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models.expressions</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">RawSQL</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">queryset</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span><span class=\"n\">val</span><span class=\"o\">=</span><span class=\"n\">RawSQL</span><span class=\"p\">(</span><span class=\"s2\">&quot;select col from sometable where othercol = </span><span class=\"si\">%s</span><span class=\"s2\">&quot;</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"n\">someparam</span><span class=\"p\">,)))</span>\n</code></pre></div>\n<p>Ces expressions brutes ne sont pas toujours portables entre moteurs de base de données (parce que vous écrivez du code SQL explicitement) et elles violent le principe DRY (ne pas se répéter), il s’agit donc de les éviter autant que possible.</p>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">Avertissement</p>\n<p>Vous devez prendre soin d’échapper systématiquement tout paramètre pouvant être contrôlé par les utilisateurs en employant <code class=\"docutils literal notranslate\"><span class=\"pre\">params</span></code> afin de vous protéger contre les <a class=\"reference internal\" href=\"/fr/1.11/topics/security/#sql-injection-protection\"><span class=\"std std-ref\">attaques par injection SQL</span></a>. <code class=\"docutils literal notranslate\"><span class=\"pre\">params</span></code> est un paramètre obligatoire pour vous forcer à confirmer que vous n’effectuez pas d’interpolation de code SQL avec des données provenant des utilisateurs.</p>\n</aside>\n</section>\n</section>\n<section id=\"technical-information\">\n<h2>Informations techniques<a class=\"heading-anchor\" href=\"#technical-information\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Vous trouverez ci-après des détails d’implémentation technique pouvant être utiles aux auteurs de bibliothèques. L’API technique et les exemples qui suivent aident à créer des expressions de requête génériques pouvant étendre les fonctionnalités intégrées que Django propose.</p>\n<section id=\"expression-api\">\n<h3>API d’expression<a class=\"heading-anchor\" href=\"#expression-api\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Les expressions de requête implémentent l”<a class=\"reference internal\" href=\"/fr/1.11/ref/models/lookups/#query-expression\"><span class=\"std std-ref\">API d’expressions de requête</span></a>, mais exposent également un certain nombre de méthodes et d’attributs supplémentaires énumérés ci-dessous. Toutes les expressions de requête doivent hériter de <code class=\"docutils literal notranslate\"><span class=\"pre\">Expression()</span></code> ou d’une sous-classe appropriée.</p>\n<p>Lorsqu’une expression de requête englobe une autre expression, elle est responsable d’appeler les méthodes appropriées de l’expression englobée.</p>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Expression\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">Expression</span></span><a class=\"heading-anchor\" href=\"#django.db.models.Expression\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Expression.contains_aggregate\">\n<span class=\"sig-name descname\"><span class=\"pre\">contains_aggregate</span></span><a class=\"heading-anchor\" href=\"#django.db.models.Expression.contains_aggregate\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Indique à Django que cette expression contient une agrégation et qu’une clause <code class=\"docutils literal notranslate\"><span class=\"pre\">GROUP</span> <span class=\"pre\">BY</span></code> doit être ajoutée à la requête.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Expression.resolve_expression\">\n<span class=\"sig-name descname\"><span class=\"pre\">resolve_expression</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">query</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">allow_joins</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">True</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">reuse</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">summarize</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">for_save</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Expression.resolve_expression\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Offre l’opportunité d’effectuer un éventuel pré-traitement ou validation de l’expression avant que celle-ci ne soit ajoutée à la requête. <code class=\"docutils literal notranslate\"><span class=\"pre\">resolve_expression()</span></code> doit aussi être appelée pour toute expression imbriquée. Une copie <code class=\"docutils literal notranslate\"><span class=\"pre\">copy()</span></code> de <code class=\"docutils literal notranslate\"><span class=\"pre\">self</span></code> devrait être renvoyée avec les éventuelles transformations nécessaires.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">query</span></code> est l’implémentation de la requête en fonction du moteur de base de données.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">allow_joins</span></code> est une valeur booléenne permettant ou interdisant l’utilisation de jointures dans la requête.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">reuse</span></code> est un ensemble de jointures réutilisables dans des scénarios de jointures multiples.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">summarize</span></code> est une valeur booléenne qui, quand elle vaut <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>, signale que la requête en cours de calcul est une requête d’agrégation terminale.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Expression.get_source_expressions\">\n<span class=\"sig-name descname\"><span class=\"pre\">get_source_expressions</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Expression.get_source_expressions\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Renvoie une liste triée d’expressions internes. Par exemple :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Sum</span><span class=\"p\">(</span><span class=\"n\">F</span><span class=\"p\">(</span><span class=\"s1\">&#39;foo&#39;</span><span class=\"p\">))</span><span class=\"o\">.</span><span class=\"n\">get_source_expressions</span><span class=\"p\">()</span>\n<span class=\"go\">[F(&#39;foo&#39;)]</span>\n</code></pre></div>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Expression.set_source_expressions\">\n<span class=\"sig-name descname\"><span class=\"pre\">set_source_expressions</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">expressions</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Expression.set_source_expressions\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Accepte une liste d’expressions et les stocke afin que <code class=\"docutils literal notranslate\"><span class=\"pre\">get_source_expressions()</span></code> puisse les restituer.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Expression.relabeled_clone\">\n<span class=\"sig-name descname\"><span class=\"pre\">relabeled_clone</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">change_map</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Expression.relabeled_clone\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Renvoie un clone (copie) de <code class=\"docutils literal notranslate\"><span class=\"pre\">self</span></code>, sachant que tout alias de colonne aura été renommé. Les alias de colonnes sont renommés lorsque des sous-requêtes sont créées. <code class=\"docutils literal notranslate\"><span class=\"pre\">relabeled_clone()</span></code> doit également être appelée pour toute expression imbriquée et attribuée au clone.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">change_map</span></code> est un dictionnaire faisant correspondre les anciens alias aux nouveaux.</p>\n<p>Exemple :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">relabeled_clone</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">change_map</span><span class=\"p\">):</span>\n    <span class=\"n\">clone</span> <span class=\"o\">=</span> <span class=\"n\">copy</span><span class=\"o\">.</span><span class=\"n\">copy</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">)</span>\n    <span class=\"n\">clone</span><span class=\"o\">.</span><span class=\"n\">expression</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">expression</span><span class=\"o\">.</span><span class=\"n\">relabeled_clone</span><span class=\"p\">(</span><span class=\"n\">change_map</span><span class=\"p\">)</span>\n    <span class=\"k\">return</span> <span class=\"n\">clone</span>\n</code></pre></div>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Expression.convert_value\">\n<span class=\"sig-name descname\"><span class=\"pre\">convert_value</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">value</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">expression</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">connection</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">context</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Expression.convert_value\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Un point d’entrée permettant à l’expression de forcer <code class=\"docutils literal notranslate\"><span class=\"pre\">value</span></code> à un type plus approprié.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Expression.get_group_by_cols\">\n<span class=\"sig-name descname\"><span class=\"pre\">get_group_by_cols</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Expression.get_group_by_cols\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Responsable du renvoi de la liste des colonnes référencées par cette expression. <code class=\"docutils literal notranslate\"><span class=\"pre\">get_group_by_cols()</span></code> doit être appelée sur toute expression imbriquée. Les objets <code class=\"docutils literal notranslate\"><span class=\"pre\">F()</span></code> en particulier détiennent une référence sur une colonne.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Expression.asc\">\n<span class=\"sig-name descname\"><span class=\"pre\">asc</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">nulls_first</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">nulls_last</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Expression.asc\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Renvoie l’expression prête à être triée dans l’ordre croissant.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">nulls_first</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">nulls_last</span></code> définissent comment les valeurs nulles sont triées.</p>\n<aside class=\"version-note version-changed\" data-version=\"1.11\">\n<p class=\"version-note-title\">Changed in Django 1.11</p><p>Les paramètres <code class=\"docutils literal notranslate\"><span class=\"pre\">nulls_last</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">nulls_first</span></code> ont été ajoutés.</p>\n</aside>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Expression.desc\">\n<span class=\"sig-name descname\"><span class=\"pre\">desc</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">nulls_first</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">nulls_last</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Expression.desc\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Renvoie l’expression prête à être triée dans l’ordre décroissant.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">nulls_first</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">nulls_last</span></code> définissent comment les valeurs nulles sont triées.</p>\n<aside class=\"version-note version-changed\" data-version=\"1.11\">\n<p class=\"version-note-title\">Changed in Django 1.11</p><p>Les paramètres <code class=\"docutils literal notranslate\"><span class=\"pre\">nulls_last</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">nulls_first</span></code> ont été ajoutés.</p>\n</aside>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Expression.reverse_ordering\">\n<span class=\"sig-name descname\"><span class=\"pre\">reverse_ordering</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Expression.reverse_ordering\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Renvoie <code class=\"docutils literal notranslate\"><span class=\"pre\">self</span></code> avec toute modification nécessaire pour inverser l’ordre de tri à l’intérieur d’un appel <code class=\"docutils literal notranslate\"><span class=\"pre\">order_by</span></code>. Comme exemple, une expression implémentant <code class=\"docutils literal notranslate\"><span class=\"pre\">NULLS</span> <span class=\"pre\">LAST</span></code> changerait sa valeur pour devenir <code class=\"docutils literal notranslate\"><span class=\"pre\">NULLS</span> <span class=\"pre\">FIRST</span></code>. Les modifications sont uniquement requises pour les expressions qui implémentent l’ordre de tri telles que <code class=\"docutils literal notranslate\"><span class=\"pre\">OrderBy</span></code>. Cette méthode est appelée lorsque <a class=\"reference internal\" href=\"/fr/1.11/ref/models/querysets/#django.db.models.query.QuerySet.reverse\" title=\"django.db.models.query.QuerySet.reverse\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">reverse()</span></code></a> est appelée sur un jeu de requête (<code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code>).</p>\n</dd></dl>\n\n</dd></dl>\n\n</section>\n<section id=\"writing-your-own-query-expressions\">\n<h3>Écriture de ses propres expressions de requête<a class=\"heading-anchor\" href=\"#writing-your-own-query-expressions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Vous pouvez écrire vos propres classes d’expression de requête qui utilisent et peuvent s’intégrer avec d’autres expressions de requête. Prenons un exemple en écrivant une implémentation de la fonction SQL <code class=\"docutils literal notranslate\"><span class=\"pre\">COALESCE</span></code>, sans utiliser les <a class=\"reference internal\" href=\"#func-expressions\"><span class=\"std std-ref\">expressions Func()</span></a> intégrées.</p>\n<p>La fonction SQL <code class=\"docutils literal notranslate\"><span class=\"pre\">COALESCE</span></code> est définie comme acceptant une liste de colonnes ou de valeurs. Elle renvoie la première colonne ou valeur qui n’est pas <code class=\"docutils literal notranslate\"><span class=\"pre\">NULL</span></code>.</p>\n<p>Commençons par définir le gabarit à utiliser pour la génération du SQL ainsi qu’une méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">__init__()</span></code> pour définir quelques attributs :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">copy</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Expression</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Coalesce</span><span class=\"p\">(</span><span class=\"n\">Expression</span><span class=\"p\">):</span>\n    <span class=\"n\">template</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;COALESCE( </span><span class=\"si\">%(expressions)s</span><span class=\"s1\"> )&#39;</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">expressions</span><span class=\"p\">,</span> <span class=\"n\">output_field</span><span class=\"p\">):</span>\n      <span class=\"nb\">super</span><span class=\"p\">(</span><span class=\"n\">Coalesce</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"n\">output_field</span><span class=\"o\">=</span><span class=\"n\">output_field</span><span class=\"p\">)</span>\n      <span class=\"k\">if</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">expressions</span><span class=\"p\">)</span> <span class=\"o\">&lt;</span> <span class=\"mi\">2</span><span class=\"p\">:</span>\n          <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span><span class=\"s1\">&#39;expressions must have at least 2 elements&#39;</span><span class=\"p\">)</span>\n      <span class=\"k\">for</span> <span class=\"n\">expression</span> <span class=\"ow\">in</span> <span class=\"n\">expressions</span><span class=\"p\">:</span>\n          <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"nb\">hasattr</span><span class=\"p\">(</span><span class=\"n\">expression</span><span class=\"p\">,</span> <span class=\"s1\">&#39;resolve_expression&#39;</span><span class=\"p\">):</span>\n              <span class=\"k\">raise</span> <span class=\"ne\">TypeError</span><span class=\"p\">(</span><span class=\"s1\">&#39;</span><span class=\"si\">%r</span><span class=\"s1\"> is not an Expression&#39;</span> <span class=\"o\">%</span> <span class=\"n\">expression</span><span class=\"p\">)</span>\n      <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">expressions</span> <span class=\"o\">=</span> <span class=\"n\">expressions</span>\n</code></pre></div>\n<p>Nous effectuons quelques validations de base sur les paramètres, y compris le minimum de 2 colonnes ou valeurs, et nous nous assurons qu’il s’agisse bien d’expressions. <code class=\"docutils literal notranslate\"><span class=\"pre\">output_field</span></code> est ici obligatoire afin que Django sache à quel type de champ de modèle attribuer l’éventuel résultat.</p>\n<p>Nous implémentons maintenant le prétraitement et la validation. Comme nous n’avons aucune validation propre à ce stade, nous ne faisons que la déléguer aux expressions imbriquées :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">resolve_expression</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">query</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">allow_joins</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span> <span class=\"n\">reuse</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">summarize</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span> <span class=\"n\">for_save</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">):</span>\n    <span class=\"n\">c</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">copy</span><span class=\"p\">()</span>\n    <span class=\"n\">c</span><span class=\"o\">.</span><span class=\"n\">is_summary</span> <span class=\"o\">=</span> <span class=\"n\">summarize</span>\n    <span class=\"k\">for</span> <span class=\"n\">pos</span><span class=\"p\">,</span> <span class=\"n\">expression</span> <span class=\"ow\">in</span> <span class=\"nb\">enumerate</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">expressions</span><span class=\"p\">):</span>\n        <span class=\"n\">c</span><span class=\"o\">.</span><span class=\"n\">expressions</span><span class=\"p\">[</span><span class=\"n\">pos</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">expression</span><span class=\"o\">.</span><span class=\"n\">resolve_expression</span><span class=\"p\">(</span><span class=\"n\">query</span><span class=\"p\">,</span> <span class=\"n\">allow_joins</span><span class=\"p\">,</span> <span class=\"n\">reuse</span><span class=\"p\">,</span> <span class=\"n\">summarize</span><span class=\"p\">,</span> <span class=\"n\">for_save</span><span class=\"p\">)</span>\n    <span class=\"k\">return</span> <span class=\"n\">c</span>\n</code></pre></div>\n<p>Ensuite, nous écrivons la méthode responsable de la génération du code SQL :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">as_sql</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">compiler</span><span class=\"p\">,</span> <span class=\"n\">connection</span><span class=\"p\">,</span> <span class=\"n\">template</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n    <span class=\"n\">sql_expressions</span><span class=\"p\">,</span> <span class=\"n\">sql_params</span> <span class=\"o\">=</span> <span class=\"p\">[],</span> <span class=\"p\">[]</span>\n    <span class=\"k\">for</span> <span class=\"n\">expression</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">expressions</span><span class=\"p\">:</span>\n        <span class=\"n\">sql</span><span class=\"p\">,</span> <span class=\"n\">params</span> <span class=\"o\">=</span> <span class=\"n\">compiler</span><span class=\"o\">.</span><span class=\"n\">compile</span><span class=\"p\">(</span><span class=\"n\">expression</span><span class=\"p\">)</span>\n        <span class=\"n\">sql_expressions</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">sql</span><span class=\"p\">)</span>\n        <span class=\"n\">sql_params</span><span class=\"o\">.</span><span class=\"n\">extend</span><span class=\"p\">(</span><span class=\"n\">params</span><span class=\"p\">)</span>\n    <span class=\"n\">template</span> <span class=\"o\">=</span> <span class=\"n\">template</span> <span class=\"ow\">or</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">template</span>\n    <span class=\"n\">data</span> <span class=\"o\">=</span> <span class=\"p\">{</span><span class=\"s1\">&#39;expressions&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;,&#39;</span><span class=\"o\">.</span><span class=\"n\">join</span><span class=\"p\">(</span><span class=\"n\">sql_expressions</span><span class=\"p\">)}</span>\n    <span class=\"k\">return</span> <span class=\"n\">template</span> <span class=\"o\">%</span> <span class=\"n\">data</span><span class=\"p\">,</span> <span class=\"n\">params</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">as_oracle</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">compiler</span><span class=\"p\">,</span> <span class=\"n\">connection</span><span class=\"p\">):</span>\n<span class=\"w\">    </span><span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">    Example of vendor specific handling (Oracle in this case).</span>\n<span class=\"sd\">    Let&#39;s make the function name lowercase.</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n    <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">as_sql</span><span class=\"p\">(</span><span class=\"n\">compiler</span><span class=\"p\">,</span> <span class=\"n\">connection</span><span class=\"p\">,</span> <span class=\"n\">template</span><span class=\"o\">=</span><span class=\"s1\">&#39;coalesce( </span><span class=\"si\">%(expressions)s</span><span class=\"s1\"> )&#39;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Les méthodes <code class=\"docutils literal notranslate\"><span class=\"pre\">as_sql()</span></code> savent gérer des paramètres nommés personnalisés, permettantaux méthodes <code class=\"docutils literal notranslate\"><span class=\"pre\">as_nomfournisseur()</span></code> de remplacer des données utilisées pour générer la chaîne SQL. Il est préférable d’utiliser des paramètres nommés pour <code class=\"docutils literal notranslate\"><span class=\"pre\">as_sql()</span></code> pour la personnalisation que de transformer <code class=\"docutils literal notranslate\"><span class=\"pre\">self</span></code> dans les méthodes <code class=\"docutils literal notranslate\"><span class=\"pre\">as_nomfournisseur()</span></code> car cela peut produire des erreurs lors du fonctionnement sur d’autres moteurs de base de données. Si votre classe s’appuie sur des attributs de classe pour définir des données, considérez la possibilité de permettre des surcharges dans votre méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">as_sql()</span></code>.</p>\n<p>Nous générons le code SQL pour chacune des <code class=\"docutils literal notranslate\"><span class=\"pre\">expressions</span></code> en utilisant la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">compiler.compile()</span></code> et en combinant les résultats avec des virgules. Puis le gabarit est complété avec nos données et le code SQL est renvoyé avec ses paramètres.</p>\n<p>Nous avons également défini une implémentation personnalisée spécifique au moteur Oracle. La fonction <code class=\"docutils literal notranslate\"><span class=\"pre\">as_oracle()</span></code> sera appelée à la place de <code class=\"docutils literal notranslate\"><span class=\"pre\">as_sql()</span></code> quand le moteur Oracle est en fonction.</p>\n<p>Finalement, nous implémentons les autres méthodes qui permettent à notre expression de requête de collaborer harmonieusement avec d’autres expressions de requête :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_source_expressions</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">expressions</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">set_source_expressions</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">expressions</span><span class=\"p\">):</span>\n    <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">expressions</span> <span class=\"o\">=</span> <span class=\"n\">expressions</span>\n</code></pre></div>\n<p>Voyons comment cela fonctionne :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">F</span><span class=\"p\">,</span> <span class=\"n\">Value</span><span class=\"p\">,</span> <span class=\"n\">CharField</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">qs</span> <span class=\"o\">=</span> <span class=\"n\">Company</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>   <span class=\"n\">tagline</span><span class=\"o\">=</span><span class=\"n\">Coalesce</span><span class=\"p\">([</span>\n<span class=\"gp\">... </span>       <span class=\"n\">F</span><span class=\"p\">(</span><span class=\"s1\">&#39;motto&#39;</span><span class=\"p\">),</span>\n<span class=\"gp\">... </span>       <span class=\"n\">F</span><span class=\"p\">(</span><span class=\"s1\">&#39;ticker_name&#39;</span><span class=\"p\">),</span>\n<span class=\"gp\">... </span>       <span class=\"n\">F</span><span class=\"p\">(</span><span class=\"s1\">&#39;description&#39;</span><span class=\"p\">),</span>\n<span class=\"gp\">... </span>       <span class=\"n\">Value</span><span class=\"p\">(</span><span class=\"s1\">&#39;No Tagline&#39;</span><span class=\"p\">)</span>\n<span class=\"gp\">... </span>       <span class=\"p\">],</span> <span class=\"n\">output_field</span><span class=\"o\">=</span><span class=\"n\">CharField</span><span class=\"p\">()))</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">for</span> <span class=\"n\">c</span> <span class=\"ow\">in</span> <span class=\"n\">qs</span><span class=\"p\">:</span>\n<span class=\"gp\">... </span>    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s2\">&quot;</span><span class=\"si\">%s</span><span class=\"s2\">: </span><span class=\"si\">%s</span><span class=\"s2\">&quot;</span> <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"n\">c</span><span class=\"o\">.</span><span class=\"n\">name</span><span class=\"p\">,</span> <span class=\"n\">c</span><span class=\"o\">.</span><span class=\"n\">tagline</span><span class=\"p\">))</span>\n<span class=\"gp\">...</span>\n<span class=\"go\">Google: Do No Evil</span>\n<span class=\"go\">Apple: AAPL</span>\n<span class=\"go\">Yahoo: Internet Company</span>\n<span class=\"go\">Django Software Foundation: No Tagline</span>\n</code></pre></div>\n</section>\n<section id=\"adding-support-in-third-party-database-backends\">\n<h3>Ajout de la prise en charge de moteurs de base de données externes<a class=\"heading-anchor\" href=\"#adding-support-in-third-party-database-backends\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Si vous utilisez un moteur de base de données qui utilise une syntaxe SQL différente pour certaines fonctions, vous pouvez ajouter sa prise en charge en greffant une nouvelle méthode dans la classe de la fonction.</p>\n<p>Admettons que nous écrivons un moteur pour SQL Server de Microsoft qui utilise l’instruction SQL <code class=\"docutils literal notranslate\"><span class=\"pre\">LEN</span></code> au lieu de <code class=\"docutils literal notranslate\"><span class=\"pre\">LENGTH</span></code> pour la fonction <a class=\"reference internal\" href=\"/fr/1.11/ref/models/database-functions/#django.db.models.functions.Length\" title=\"django.db.models.functions.Length\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Length</span></code></a>. Nous allons greffer une nouvelle méthode appelée <code class=\"docutils literal notranslate\"><span class=\"pre\">as_sqlserver()</span></code> dans la classe <code class=\"docutils literal notranslate\"><span class=\"pre\">Length</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models.functions</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Length</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">sqlserver_length</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">compiler</span><span class=\"p\">,</span> <span class=\"n\">connection</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">as_sql</span><span class=\"p\">(</span><span class=\"n\">compiler</span><span class=\"p\">,</span> <span class=\"n\">connection</span><span class=\"p\">,</span> <span class=\"n\">function</span><span class=\"o\">=</span><span class=\"s1\">&#39;LEN&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">Length</span><span class=\"o\">.</span><span class=\"n\">as_sqlserver</span> <span class=\"o\">=</span> <span class=\"n\">sqlserver_length</span>\n</code></pre></div>\n<p>Il est aussi possible de personnaliser le code SQL en utilisant le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">template</span></code> de <code class=\"docutils literal notranslate\"><span class=\"pre\">as_sql()</span></code>.</p>\n<p>Nous utilisons <code class=\"docutils literal notranslate\"><span class=\"pre\">as_sqlserver()</span></code> parce que <code class=\"docutils literal notranslate\"><span class=\"pre\">django.db.connection.vendor</span></code> renvoie <code class=\"docutils literal notranslate\"><span class=\"pre\">sqlserver</span></code> comme moteur.</p>\n<p>Les moteurs tiers peuvent inscrire leurs fonctions dans le fichier <code class=\"docutils literal notranslate\"><span class=\"pre\">__init__.py</span></code> de premier niveau du paquet de moteur ou dans un fichier (ou paquet) <code class=\"docutils literal notranslate\"><span class=\"pre\">expressions.py</span></code> de premier niveauqui est lui-même importé depuis <code class=\"docutils literal notranslate\"><span class=\"pre\">__init__.py</span></code>.</p>\n<p>Pour les projets d’utilisateurs qui souhaitent adapter le moteur qu’ils utilisent, ce code devrait se trouver dans une méthode <a class=\"reference internal\" href=\"/fr/1.11/ref/applications/#django.apps.AppConfig.ready\" title=\"django.apps.AppConfig.ready\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">AppConfig.ready()</span></code></a>.</p>\n</section>\n</section>","rootId":"query-expressions","toc":[{"title":"Arithmétique prise en charge","anchor":"supported-arithmetic","children":[]},{"title":"Quelques exemples","anchor":"some-examples","children":[]},{"title":"Expressions intégrées","anchor":"built-in-expressions","children":[{"title":"Expressions F()","anchor":"f-expressions","children":[{"title":"Prévention des conflits de concurrence avec F()","anchor":"avoiding-race-conditions-using-f","children":[]},{"title":"Les attributions par F() persistent après Model.save()","anchor":"f-assignments-persist-after-model-save","children":[]},{"title":"Utilisation de F() dans les filtres","anchor":"using-f-in-filters","children":[]},{"title":"Utilisation de F() avec les annotations","anchor":"using-f-with-annotations","children":[]}]},{"title":"Expressions Func()","anchor":"func-expressions","children":[]},{"title":"Expressions Aggregate()","anchor":"aggregate-expressions","children":[]},{"title":"Création de ses propres fonctions d’agrégation","anchor":"creating-your-own-aggregate-functions","children":[]},{"title":"Expressions Value()","anchor":"value-expressions","children":[]},{"title":"Expressions ExpressionWrapper()","anchor":"expressionwrapper-expressions","children":[]},{"title":"Expressions conditionnelles","anchor":"conditional-expressions","children":[]},{"title":"Expressions Subquery()","anchor":"subquery-expressions","children":[{"title":"Référencement des colonnes de la requête parente","anchor":"referencing-columns-from-the-outer-queryset","children":[]},{"title":"Limite d’une sous-requête à une seule colonne","anchor":"limiting-a-subquery-to-a-single-column","children":[]},{"title":"Limite de la sous-requête à une seule ligne","anchor":"limiting-the-subquery-to-a-single-row","children":[]},{"title":"Sous-requêtes Exists()","anchor":"exists-subqueries","children":[]},{"title":"Filtrage sur une expression Subquery","anchor":"filtering-on-a-subquery-expression","children":[]},{"title":"Utilisation d’agrégation dans une expression Subquery","anchor":"using-aggregates-within-a-subquery-expression","children":[]}]},{"title":"Expressions SQL brutes","anchor":"raw-sql-expressions","children":[]}]},{"title":"Informations techniques","anchor":"technical-information","children":[{"title":"API d’expression","anchor":"expression-api","children":[]},{"title":"Écriture de ses propres expressions de requête","anchor":"writing-your-own-query-expressions","children":[]},{"title":"Ajout de la prise en charge de moteurs de base de données externes","anchor":"adding-support-in-third-party-database-backends","children":[]}]}],"breadcrumbs":[{"docname":"ref/index","title":"Référence de l’API","url":"/fr/1.11/ref/"},{"docname":"ref/models/index","title":"Modèles","url":"/fr/1.11/ref/models/"}],"prev":{"docname":"ref/models/lookups","title":"API de référence des expressions de recherche","url":"/fr/1.11/ref/models/lookups/"},"next":{"docname":"ref/models/conditional-expressions","title":"Expressions conditionnelles","url":"/fr/1.11/ref/models/conditional-expressions/"},"formats":{"html":"/fr/1.11/ref/models/expressions/","markdown":"/fr/1.11/ref/models/expressions.md","json":"/fr/1.11/ref/models/expressions.json"},"source":"https://github.com/django/django/blob/stable/1.11.x/docs/ref/models/expressions.txt","official":"https://docs.djangoproject.com/fr/1.11/ref/models/expressions/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0","1.11","1.10","1.9"],"inLocales":["en","fr","ja","id","pt-br","ko","es","el","pl"]}